From 71e7d0492b70417a4b3ea3356dfc8ccf8c3cc11f Mon Sep 17 00:00:00 2001 From: Brian Koehmstedt <1261658+bkoehm@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:05:03 -0800 Subject: [PATCH] Grails 7: Update usercache page to display statistics for a JSR-107 Cache --- .../spec/ExtendedSecurityInfoSpec.groovy | 23 +++++++- .../views/securityInfo/usercache.gsp | 52 ++++++++----------- .../spec/DefaultSecurityInfoSpec.groovy | 25 +++++++-- .../ui/SecurityInfoController.groovy | 2 +- .../messages.spring-security-ui.properties | 15 +++--- .../views/securityInfo/usercache.gsp | 52 ++++++++----------- 6 files changed, 92 insertions(+), 77 deletions(-) diff --git a/examples/extended/src/integration-test/groovy/spec/ExtendedSecurityInfoSpec.groovy b/examples/extended/src/integration-test/groovy/spec/ExtendedSecurityInfoSpec.groovy index a398e660..a9f82873 100644 --- a/examples/extended/src/integration-test/groovy/spec/ExtendedSecurityInfoSpec.groovy +++ b/examples/extended/src/integration-test/groovy/spec/ExtendedSecurityInfoSpec.groovy @@ -1,10 +1,14 @@ package spec import grails.testing.mixin.integration.Integration +import org.springframework.security.core.userdetails.User +import org.springframework.security.core.userdetails.UserCache @Integration class ExtendedSecurityInfoSpec extends AbstractSecuritySpec { + UserCache userCache + void testConfig() { when: go 'securityInfo/config' @@ -37,12 +41,27 @@ class ExtendedSecurityInfoSpec extends AbstractSecuritySpec { } void testUsercache() { + given: + userCache.putUserInCache(new User('testuser', 'pw', [])) + + when: + go 'securityInfo/usercache' + + then: + assertContentContains 'UserCache class: org.ehcache.jsr107.Eh107Cache' + assertContentContains 'testuser' + + cleanup: + userCache.removeUserFromCache('testuser') + } + + void testEmptyUsercache() { when: go 'securityInfo/usercache' then: - assertContentContains 'UserCache class: net.sf.ehcache.Cache' - assertContentContains 'Memory Store Object Count 0' + assertContentContains 'UserCache class: org.ehcache.jsr107.Eh107Cache' + assertContentDoesNotContain'testuser' } void testFilterChains() { diff --git a/examples/simple/grails-app/views/securityInfo/usercache.gsp b/examples/simple/grails-app/views/securityInfo/usercache.gsp index 30366330..b7c21879 100644 --- a/examples/simple/grails-app/views/securityInfo/usercache.gsp +++ b/examples/simple/grails-app/views/securityInfo/usercache.gsp @@ -8,65 +8,55 @@

- - - ${cache.size} - - - - ${cache.status} - ${cache.name} - - - ${cache.guid} - - + - ${cache.statistics.cacheHitCount()} + ${cache.statisticsMBean.cacheHits} - - ${cache.statistics.localHeapHitCount()} + + ${cache.statisticsMBean.cacheHitPercentage} - - ${cache.statistics.localDiskHitCount()} + + ${cache.statisticsMBean.cacheMisses} - - ${cache.statistics.cacheMissCount()} + + ${cache.statisticsMBean.cacheMissPercentage} - - ${cache.statistics.size} + + ${cache.statisticsMBean.cacheGets} - - ${cache.statistics.localHeapSize} + + ${cache.statisticsMBean.cachePuts} - - ${cache.statistics.localDiskSize} + + ${cache.statisticsMBean.cacheRemovals} - ${cache.statistics.cacheEvictedCount()} + ${cache.statisticsMBean.cacheEvictions} - + - - ${it} - ${cache.get(it)?.value} + + + ${it.key} + ${it.value} + diff --git a/examples/simple/src/integration-test/groovy/spec/DefaultSecurityInfoSpec.groovy b/examples/simple/src/integration-test/groovy/spec/DefaultSecurityInfoSpec.groovy index 8ebe889b..dfff080b 100644 --- a/examples/simple/src/integration-test/groovy/spec/DefaultSecurityInfoSpec.groovy +++ b/examples/simple/src/integration-test/groovy/spec/DefaultSecurityInfoSpec.groovy @@ -1,10 +1,14 @@ package spec import grails.testing.mixin.integration.Integration +import org.springframework.security.core.userdetails.User +import org.springframework.security.core.userdetails.UserCache @Integration class DefaultSecurityInfoSpec extends AbstractSecuritySpec { + UserCache userCache + void testConfig() { when: go 'securityInfo/config' @@ -32,17 +36,32 @@ class DefaultSecurityInfoSpec extends AbstractSecuritySpec { go 'securityInfo/currentAuth' then: - assertContentContains 'org.springframework.security.web.authentication.WebAuthenticationDetails' + assertContentContains 'Details WebAuthenticationDetails' assertContentContains '__grails.anonymous.user__' } void testUsercache() { + given: + userCache.putUserInCache(new User('testuser', 'pw', [])) + + when: + go 'securityInfo/usercache' + + then: + assertContentContains 'UserCache class: org.ehcache.jsr107.Eh107Cache' + assertContentContains 'testuser' + + cleanup: + userCache.removeUserFromCache('testuser') + } + + void testEmptyUsercache() { when: go 'securityInfo/usercache' then: - assertContentContains 'UserCache class: net.sf.ehcache.Cache' - assertContentContains 'Memory Store Object Count 0' + assertContentContains 'UserCache class: org.ehcache.jsr107.Eh107Cache' + assertContentDoesNotContain'testuser' } void testFilterChains() { diff --git a/plugin/grails-app/controllers/grails/plugin/springsecurity/ui/SecurityInfoController.groovy b/plugin/grails-app/controllers/grails/plugin/springsecurity/ui/SecurityInfoController.groovy index 6291e5d5..f81dcfad 100644 --- a/plugin/grails-app/controllers/grails/plugin/springsecurity/ui/SecurityInfoController.groovy +++ b/plugin/grails-app/controllers/grails/plugin/springsecurity/ui/SecurityInfoController.groovy @@ -52,7 +52,7 @@ class SecurityInfoController { } def usercache() { - [cache: conf.cacheUsers ? userCache.cache : false] + [cache: conf.cacheUsers ? userCache.cache.nativeCache : false] } def filterChains() { diff --git a/plugin/grails-app/i18n/messages.spring-security-ui.properties b/plugin/grails-app/i18n/messages.spring-security-ui.properties index bf496f22..d4daf369 100644 --- a/plugin/grails-app/i18n/messages.spring-security-ui.properties +++ b/plugin/grails-app/i18n/messages.spring-security-ui.properties @@ -37,7 +37,7 @@ spring.security.ui.menu.securityInfo.mappings Mappings spring.security.ui.menu.securityInfo.providers Authentication Providers spring.security.ui.menu.securityInfo.secureChannel Secure Channel Definition spring.security.ui.menu.securityInfo.usercache User Cache -spring.security.ui.menu.securityInfo.usercache.cachedUsers {0} Cached User(s) +spring.security.ui.menu.securityInfo.usercache.cachedUsers Cached User(s) spring.security.ui.menu.securityInfo.usercache.statistics Statistics spring.security.ui.menu.securityInfo.voters Voters spring.security.ui.menu.user Users @@ -93,18 +93,15 @@ spring.security.ui.info.usercache.classname UserCache class: {0} spring.security.ui.info.usercache.disabled Not Caching Users spring.security.ui.info.usercache.header.attribute Attribute spring.security.ui.info.usercache.header.value Value -spring.security.ui.info.usercache.label.guid GUID spring.security.ui.info.usercache.label.name Name -spring.security.ui.info.usercache.label.size Size spring.security.ui.info.usercache.label.stats.cacheHits Cache Hits +spring.security.ui.info.usercache.label.stats.cacheHitPercentage Cache Hit Percentage spring.security.ui.info.usercache.label.stats.cacheMisses Cache Misses -spring.security.ui.info.usercache.label.stats.diskHits On-disk Hits -spring.security.ui.info.usercache.label.stats.diskObjectCount Disk Store Object Count +spring.security.ui.info.usercache.label.stats.cacheMissPercentage Cache Miss Percentage +spring.security.ui.info.usercache.label.stats.cacheGets Cache Gets +spring.security.ui.info.usercache.label.stats.cachePuts Cache Puts +spring.security.ui.info.usercache.label.stats.cacheRemovals Cache Removals spring.security.ui.info.usercache.label.stats.evictionCount Eviction Count -spring.security.ui.info.usercache.label.stats.memoryHits In-memory Hits -spring.security.ui.info.usercache.label.stats.memoryObjectCount Memory Store Object Count -spring.security.ui.info.usercache.label.stats.objectCount Object Count -spring.security.ui.info.usercache.label.status Status spring.security.ui.info.usercache.statistics.header.attribute Attribute spring.security.ui.info.usercache.statistics.header.value Value spring.security.ui.info.voters.header.className Class Name diff --git a/plugin/grails-app/views/securityInfo/usercache.gsp b/plugin/grails-app/views/securityInfo/usercache.gsp index 30366330..b7c21879 100644 --- a/plugin/grails-app/views/securityInfo/usercache.gsp +++ b/plugin/grails-app/views/securityInfo/usercache.gsp @@ -8,65 +8,55 @@

- - - ${cache.size} - - - - ${cache.status} - ${cache.name} - - - ${cache.guid} - - + - ${cache.statistics.cacheHitCount()} + ${cache.statisticsMBean.cacheHits} - - ${cache.statistics.localHeapHitCount()} + + ${cache.statisticsMBean.cacheHitPercentage} - - ${cache.statistics.localDiskHitCount()} + + ${cache.statisticsMBean.cacheMisses} - - ${cache.statistics.cacheMissCount()} + + ${cache.statisticsMBean.cacheMissPercentage} - - ${cache.statistics.size} + + ${cache.statisticsMBean.cacheGets} - - ${cache.statistics.localHeapSize} + + ${cache.statisticsMBean.cachePuts} - - ${cache.statistics.localDiskSize} + + ${cache.statisticsMBean.cacheRemovals} - ${cache.statistics.cacheEvictedCount()} + ${cache.statisticsMBean.cacheEvictions} - + - - ${it} - ${cache.get(it)?.value} + + + ${it.key} + ${it.value} +