This is an automated email from the ASF dual-hosted git repository.
jamesfredley pushed a commit to branch fix/forge-analytics-security
in repository https://gitbox.apache.org/repos/asf/grails-core.git
The following commit(s) were added to refs/heads/fix/forge-analytics-security
by this push:
new f3cd7001af Scope no-op transaction factory to datasource-disabled tests
f3cd7001af is described below
commit f3cd7001afcb1b952f3abd56220f71460042f687
Author: James Fredley <[email protected]>
AuthorDate: Fri Jul 17 19:51:55 2026 -0400
Scope no-op transaction factory to datasource-disabled tests
Assisted-by: opencode:gpt-5.6-sol
---
.../AnalyticsControllerSecuritySpec.groovy | 52 ++++++++++++++++++++++
.../NoOpTransactionOperationsFactory.groovy | 1 +
2 files changed, 53 insertions(+)
diff --git
a/grails-forge/grails-forge-analytics-postgres/src/test/groovy/org/grails/forge/analytics/postgres/AnalyticsControllerSecuritySpec.groovy
b/grails-forge/grails-forge-analytics-postgres/src/test/groovy/org/grails/forge/analytics/postgres/AnalyticsControllerSecuritySpec.groovy
index 4f4a55d262..9309780b93 100644
---
a/grails-forge/grails-forge-analytics-postgres/src/test/groovy/org/grails/forge/analytics/postgres/AnalyticsControllerSecuritySpec.groovy
+++
b/grails-forge/grails-forge-analytics-postgres/src/test/groovy/org/grails/forge/analytics/postgres/AnalyticsControllerSecuritySpec.groovy
@@ -54,6 +54,7 @@ import jakarta.inject.Inject
class AnalyticsControllerSecuritySpec extends Specification {
@Inject @Client('/') HttpClient client
+ @Inject @Client('/analytics') HttpClient analyticsClient
@Inject ApplicationRepository applicationRepository
@Inject FeatureRepository featureRepository
@Inject JdbcOperations jdbcOperations
@@ -90,6 +91,48 @@ class AnalyticsControllerSecuritySpec extends Specification {
0 * applicationRepository._
}
+ void 'report generation data accepts valid bearer token'() {
+ given:
+ Generated generated = new Generated(
+ ApplicationType.WEB,
+ GormImpl.HIBERNATE5,
+ ServletImpl.TOMCAT,
+ DevelopmentReloading.DEVTOOLS,
+ JdkVersion.DEFAULT_OPTION
+ )
+ generated.setSelectedFeatures([new
SelectedFeature('google-cloud-function')])
+ applicationRepository.save(_) >> { arguments -> arguments[0] }
+
+ when:
+ def response =
client.toBlocking().exchange(HttpRequest.POST('/analytics/report',
generated).bearerAuth(validToken()), String)
+
+ then:
+ response.status == HttpStatus.ACCEPTED
+ 1 * featureRepository.saveAll(_)
+ 0 * jdbcOperations._
+ }
+
+ void 'report generation data accepts valid bearer token with analytics
client'() {
+ given:
+ Generated generated = new Generated(
+ ApplicationType.WEB,
+ GormImpl.HIBERNATE5,
+ ServletImpl.TOMCAT,
+ DevelopmentReloading.DEVTOOLS,
+ JdkVersion.DEFAULT_OPTION
+ )
+ generated.setSelectedFeatures([new
SelectedFeature('google-cloud-function')])
+ applicationRepository.save(_) >> { arguments -> arguments[0] }
+
+ when:
+ def response =
analyticsClient.toBlocking().exchange(HttpRequest.POST('report',
generated).bearerAuth(validToken()), String)
+
+ then:
+ response.status == HttpStatus.ACCEPTED
+ 1 * featureRepository.saveAll(_)
+ 0 * jdbcOperations._
+ }
+
void 'report generation data rejects bearer token with wrong audience'() {
given:
Generated generated = new Generated(
@@ -161,6 +204,15 @@ class AnalyticsControllerSecuritySpec extends
Specification {
]).orElseThrow()
}
+ @NonNull
+ private String validToken() {
+ tokenGenerator.generateToken([
+ sub: '1234567890',
+ iss: 'forge-test',
+ aud: 'forge-analytics'
+ ]).orElseThrow()
+ }
+
@NonNull
private String wrongCallerToken() {
tokenGenerator.generateToken([
diff --git
a/grails-forge/grails-forge-analytics-postgres/src/test/groovy/org/grails/forge/analytics/postgres/NoOpTransactionOperationsFactory.groovy
b/grails-forge/grails-forge-analytics-postgres/src/test/groovy/org/grails/forge/analytics/postgres/NoOpTransactionOperationsFactory.groovy
index a94187ae2d..59919658a1 100644
---
a/grails-forge/grails-forge-analytics-postgres/src/test/groovy/org/grails/forge/analytics/postgres/NoOpTransactionOperationsFactory.groovy
+++
b/grails-forge/grails-forge-analytics-postgres/src/test/groovy/org/grails/forge/analytics/postgres/NoOpTransactionOperationsFactory.groovy
@@ -33,6 +33,7 @@ import java.util.Optional
@Factory
@Requires(env = 'test')
+@Requires(property = 'datasources.default.enabled', value = 'false')
class NoOpTransactionOperationsFactory {
@Singleton