diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d8319be27..bf5e958e0 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -13,7 +13,7 @@ env:
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
@@ -31,6 +31,30 @@ jobs:
- run: npm install
+ - name: Validate Gradle wrapper
+ uses: gradle/wrapper-validation-action@v1.0.6
+
+ - name: Install and start elasticsearch
+ run: |
+ curl https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.16.3-amd64.deb -o elasticsearch.deb
+ sudo dpkg -i --force-confnew elasticsearch.deb
+ sudo chown -R elasticsearch:elasticsearch /etc/default/elasticsearch
+ sudo sh -c 'echo ES_JAVA_OPTS=\"-Xmx1g -Xms1g\" >> /etc/default/elasticsearch'
+ sudo service elasticsearch restart
+
+ - name: Setup required MERIT folders
+ run: |
+ sudo mkdir -p /data/fieldcapture/cache
+ sudo chmod o+xw /data
+ sudo chmod o+xw /data/fieldcapture
+ sudo chmod o+xw /data/fieldcapture/cache
+
+ - name: Install and start mongodb
+ uses: supercharge/mongodb-github-action@1.7.0
+ with:
+ mongodb-version: '5.0'
+
+
- name: Read the biocollect version from the gradle.properties file
id: read_property
uses: christian-draeger/read-properties@1.1.0
@@ -53,22 +77,28 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
- name: build biocollect before running js unit test to compile dependent js templates
- uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
+ uses: gradle/gradle-build-action@v2.4.0
with:
- arguments: build
+ arguments: _Events
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run javascript unit tests
run: node_modules/karma/bin/karma start karma.conf.js --single-run --browsers ChromeHeadless
+ - name: Run BioCollect functional tests
+ run: ./src/main/scripts/runFunctionalTests.sh chromeHeadless /tmp/ecodata feature/cognito
+ env:
+ GITHUB_ACTOR: ${{env.GITHUB_ACTOR}}
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
+
- name: Clean to remove clover instrumentation
- uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
+ uses: gradle/gradle-build-action@v2.4.0
with:
arguments: clean
- name: Publish the JAR to the repository
- uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
+ uses: gradle/gradle-build-action@v2.4.0
with:
arguments: publish
env:
diff --git a/build.gradle b/build.gradle
index 7a98bae71..b19c731dd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,7 @@
buildscript {
repositories {
mavenLocal()
+ maven { url "https://plugins.gradle.org/m2/" }
maven { url "https://repo.grails.org/grails/core" }
maven { url "https://nexus.ala.org.au/content/groups/public/" }
}
@@ -12,6 +13,8 @@ buildscript {
classpath 'com.bertramlabs.plugins:sass-asset-pipeline:3.2.5'
classpath 'com.bmuschko:gradle-clover-plugin:3.0.1'
classpath 'org.grails.plugins:quartz:2.0.13'
+ classpath "gradle.plugin.com.github.william-hill-online:wiremock-gradle-plugin:0.4.3"
+ classpath "com.github.tomakehurst:wiremock-jre8-standalone:2.28.0"
}
}
@@ -27,6 +30,7 @@ apply plugin: "org.grails.grails-web"
apply plugin:"com.github.erdi.webdriver-binaries"
apply plugin: "com.bertramlabs.asset-pipeline"
apply plugin: "org.grails.grails-gsp"
+apply plugin: "com.github.william-hill-online.wiremock"
if (Boolean.valueOf(enableClover)) {
apply from: "${project.projectDir}/gradle/clover.gradle"
@@ -81,6 +85,9 @@ dependencies {
implementation "org.grails:grails-plugin-url-mappings"
implementation "org.grails:grails-plugin-interceptors"
implementation "org.grails.plugins:cache"
+ implementation "org.grails.plugins:cache-ehcache:3.0.0"
+ runtimeOnly "javax.xml.bind:jaxb-api:2.3.1"
+ runtimeOnly "org.glassfish.jaxb:jaxb-runtime:2.3.1"
implementation "org.grails.plugins:async"
implementation "org.grails:grails-async-gpars"
implementation "org.grails.plugins:scaffolding"
@@ -129,14 +136,15 @@ dependencies {
implementation 'org.apache.poi:poi-ooxml-schemas:4.1.2'
implementation "org.grails.plugins:ala-admin-plugin:2.3.0"
- implementation ("org.grails.plugins:ala-auth:5.1.1")
- implementation "org.grails.plugins:ala-ws-security-plugin:4.1.2"
- runtimeOnly "org.grails.plugins:ala-bootstrap3:4.2.0"
+ implementation ("org.grails.plugins:ala-auth:$alaSecurityLibsVersion")
+ implementation ("org.grails.plugins:ala-ws-plugin:$alaSecurityLibsVersion")
+ implementation "org.grails.plugins:ala-ws-security-plugin:$alaSecurityLibsVersion"
+ implementation "au.org.ala:userdetails-service-client:$alaSecurityLibsVersion"
+ runtimeOnly "org.grails.plugins:ala-bootstrap3:4.1.0"
// swagger API
implementation 'au.org.ala.plugins:openapi:1.1.0'
- implementation "au.org.ala:userdetails-service-client:1.5.0"
implementation "org.codehaus.groovy.modules.http-builder:http-builder:0.7.1"
implementation 'au.org.ala:ala-cas-client:2.5'
runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
@@ -146,7 +154,7 @@ dependencies {
if (!Boolean.valueOf(inplace)) {
implementation "org.grails.plugins:ala-map-plugin:3.0.1"
- implementation "org.grails.plugins:ecodata-client-plugin:6.0"
+ implementation "org.grails.plugins:ecodata-client-plugin:6.1-COGNITO-SNAPSHOT"
}
testCompileOnly "org.grails:grails-test-mixins:3.3.0"
@@ -154,12 +162,12 @@ dependencies {
testImplementation "org.mockito:mockito-core"
testImplementation "org.grails:grails-web-testing-support"
testImplementation "org.grails.plugins:geb"
- testImplementation "org.seleniumhq.selenium:selenium-remote-driver:4.0.0"
- testImplementation "org.seleniumhq.selenium:selenium-api:4.0.0"
- testImplementation "org.seleniumhq.selenium:selenium-support:4.0.0"
- testRuntimeOnly "org.seleniumhq.selenium:selenium-chrome-driver:4.0.0"
- testRuntimeOnly "org.seleniumhq.selenium:selenium-firefox-driver:4.0.0"
- testCompileOnly "com.github.tomakehurst:wiremock-jre8-standalone:2.28.0"
+ testImplementation "com.github.tomakehurst:wiremock-jre8-standalone:2.28.0"
+ testImplementation "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion"
+ testImplementation "org.seleniumhq.selenium:selenium-api:$seleniumVersion"
+ testImplementation "org.seleniumhq.selenium:selenium-support:$seleniumVersion"
+ testRuntimeOnly "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion"
+ testRuntimeOnly "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion"
testCompileOnly "com.codeborne:phantomjsdriver:1.3.0"
}
@@ -236,29 +244,22 @@ tasks.withType(Test) {
useJUnitPlatform()
}
-webdriverBinaries {
- if (!System.getenv().containsKey('GITHUB_ACTIONS')) {
- chromedriver {
- versionRegexp = '.*'
- architecture = 'X86_64'
- fallbackTo32Bit = true
- }
- geckodriver '0.30.0'
- }
-}
-
tasks.withType(Test) {
systemProperty "geb.env", System.getProperty('geb.env')
systemProperty "geb.build.reportsDir", reporting.file("geb/integrationTest")
- if (!System.getenv().containsKey('GITHUB_ACTIONS')) {
- systemProperty 'webdriver.chrome.driver', System.getProperty('webdriver.chrome.driver')
- systemProperty 'webdriver.gecko.driver', System.getProperty('webdriver.gecko.driver')
- } else {
- systemProperty 'webdriver.chrome.driver', "${System.getenv('CHROMEWEBDRIVER')}/chromedriver"
- systemProperty 'webdriver.gecko.driver', "${System.getenv('GECKOWEBDRIVER')}/geckodriver"
+ systemProperty 'webdriver.chrome.driver', System.getProperty('webdriver.chrome.driver')
+ systemProperty 'webdriver.gecko.driver', System.getProperty('webdriver.gecko.driver')
+ testLogging {
+ events "passed", "skipped", "failed"
+ exceptionFormat "full"
+ showStandardStreams true
}
}
+wiremock {
+ dir "${project.projectDir}/src/integration-test/resources/wiremock/"
+ params "--port=8018 --global-response-templating --local-response-templating"
+}
assets {
minifyJs = true
diff --git a/gradle.properties b/gradle.properties
index b83ac86db..14cb069c5 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,7 +1,9 @@
-biocollectVersion=6.6.1-SNAPSHOT
+biocollectVersion=6.7-SNAPSHOT
grailsVersion=5.1.9
grailsGradlePluginVersion=5.1.5
assetPipelineVersion=3.3.4
+alaSecurityLibsVersion=6.1.0
+seleniumVersion=4.9.0
groovyVersion=3.0.7
gorm.version=7.2.1
org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx2048M
diff --git a/grails-app/conf/application.groovy b/grails-app/conf/application.groovy
index 57c5f55ea..296b787ad 100644
--- a/grails-app/conf/application.groovy
+++ b/grails-app/conf/application.groovy
@@ -32,11 +32,13 @@ environments {
sender = "biocollect-dev@ala.org.au"
debugUI = true
loggerLevel = "DEBUG"
+ auth.baseURL = "https://auth-test.ala.org.au"
}
test {
- debugUI: false
- loggerLevel: "DEBUG"
+ spring.autoconfigure.exclude="au.org.ala.ws.security.AlaWsSecurityConfiguration"
+ debugUI = false
+ loggerLevel = "DEBUG"
server.port = "8087"
grails.host = "http://devt.ala.org.au"
serverName = "${grails.host}:${server.port}"
@@ -46,15 +48,20 @@ environments {
app.default.hub='ala'
runWithNoExternalConfig = true
wiremock.port = 8018
+ grails.config.locations = []
+ security.oidc.discoveryUri = "http://localhost:${wiremock.port}/cas/oidc/.well-known"
+ security.oidc.allowUnsignedIdTokens = true
def casBaseUrl = "http://devt.ala.org.au:${wiremock.port}"
security.cas.appServerName=serverName
security.cas.contextPath=
security.cas.casServerName="${casBaseUrl}"
+ auth.baseURL = "${casBaseUrl}"
security.cas.casServerUrlPrefix="${casBaseUrl}/cas"
security.cas.loginUrl="${security.cas.casServerUrlPrefix}/login"
security.cas.casLoginUrl="${security.cas.casServerUrlPrefix}/login"
security.cas.logoutUrl="${security.cas.casServerUrlPrefix}/logout"
+ security.jwt.discoveryUri="${casBaseUrl}/cas/oidc/.well-known"
userDetails.url = "${casBaseUrl}/userdetails/userDetails/"
userDetailsSingleUrl = "${userDetails.Url}getUserDetails"
userDetailsUrl = "${userDetatails.url}getUserListFull"
@@ -66,6 +73,14 @@ environments {
ecodata.service.url = 'http://devt.ala.org.au:8080/ws'
pdfgen.baseURL = "http://devt.ala.org.au:${wiremock.port}/"
api_key='testapikey'
+ grails.cache.config = {
+ diskStore {
+ path '/tmp'
+ }
+ defaultCache {
+ overflowToDisk false
+ }
+ }
spatial.baseUrl = "http://localhost:${wiremock.port}"
spatial.baseURL = "http://localhost:${wiremock.port}"
spatial.geoserverUrl= spatial.baseUrl + "/geoserver"
@@ -86,9 +101,37 @@ environments {
sender = "biocollect-local@ala.org.au"
debugUI = false
loggerLevel = "INFO"
+ auth.baseURL = "https://auth.ala.org.au"
}
}
+casUrl = "${auth.baseURL}/cas/logout"
+appUrl = grails.serverURL
+
+security.cas.enabled = false
+security.cas.uriExclusionFilterPattern = ['/assets/.*','/uploads/.*']
+security.cas.uriFilterPattern = []
+security.cas.readOnlyOfficerRole= "ROLE_FC_READ_ONLY"
+security.cas.alaAdminRole = "ROLE_ADMIN"
+security.cas.officerRole = "ROLE_FC_OFFICER"
+security.cas.adminRole = "ROLE_FC_ADMIN"
+security.cas.casServerName= "${auth.baseURL}"
+security.cas.casServerLoginUrl= "${auth.baseURL}/cas/login"
+security.cas.casServerUrlPrefix= "${auth.baseURL}/cas"
+security.cas.logoutUrl= "${security.cas.casServerUrlPrefix}/logout"
+security.cas.loginUrl= "${security.cas.casServerUrlPrefix}/login"
+
+security.oidc.enabled= true
+security.oidc.discoveryUri= "${auth.baseURL}/cas/oidc/.well-known"
+security.oidc.clientId= "changeMe"
+security.oidc.secret= "changeMe"
+security.oidc.scope= "openid,profile,email,ala,roles"
+security.oidc.allowUnsignedIdTokens= true
+
+security.jwt.enabled= true
+security.jwt.discoveryUri= "${auth.baseURL}/cas/oidc/.well-known"
+security.jwt.fallbackToLegacyBehaviour= true
+
dataAccessMethods = [
"oasrdfs",
"oaordfs",
diff --git a/grails-app/conf/application.yml b/grails-app/conf/application.yml
index e27dfd937..b2aced28e 100644
--- a/grails-app/conf/application.yml
+++ b/grails-app/conf/application.yml
@@ -19,39 +19,6 @@ app:
userId: "X-ALA-userId"
hostName: "X-ALA-hostname"
-auth:
- baseURL: "https://auth.ala.org.au"
-
-casUrl: "${auth.baseURL}/cas/logout"
-appUrl: "http://devt.ala.org.au:8087/"
-
-security:
- cas:
- enabled: false
- uriExclusionFilterPattern: ['/assets/.*','/uploads/.*']
- uriFilterPattern: []
- readOnlyOfficerRole: "ROLE_FC_READ_ONLY"
- alaAdminRole : "ROLE_ADMIN"
- officerRole : "ROLE_FC_OFFICER"
- adminRole : "ROLE_FC_ADMIN"
- casServerName: "${auth.baseURL}"
- casServerLoginUrl: "${auth.baseURL}/cas/login"
- casServerUrlPrefix: "${auth.baseURL}/cas"
- logoutUrl: "${security.cas.casServerUrlPrefix}/logout"
- loginUrl: "${security.cas.casServerUrlPrefix}/login"
-
- oidc:
- enabled: true
- discoveryUri: "${auth.baseURL}/cas/oidc/.well-known"
- clientId: "changeMe"
- secret: "changeMe"
- scope: "openid,profile,email,ala,roles"
- allowUnsignedIdTokens: true
- jwt:
- enabled: true
- discoveryUri: "${auth.baseURL}/cas/oidc/.well-known"
- fallbackToLegacyBehaviour: true
-
#External URL
aekosEnabled: false
enableReporting: true
@@ -169,15 +136,8 @@ grails:
codegen:
defaultPackage: au.org.ala.biocollect
cache:
- defaults:
- eternal: true
- overflowToDisk: false
- maxElementsInMemory: 20000
- timeToLiveSeconds: 3600
- name: 'vocabListCache'
ehcache:
- cacheManagerName : "${appName}-ehcache"
- reloadable : false
+ ehcacheXmlLocation: 'classpath:biocollect-ehcache.xml'
mime:
file:
extensions: true
@@ -342,5 +302,11 @@ bootstrap4:
skin:
layout: "bs4"
+---
+
+grails:
+ cors:
+ enabled: true
+
fathom:
enabled: true
\ No newline at end of file
diff --git a/grails-app/conf/biocollect-ehcache.xml b/grails-app/conf/biocollect-ehcache.xml
new file mode 100644
index 000000000..85d7da2e9
--- /dev/null
+++ b/grails-app/conf/biocollect-ehcache.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+ 1
+
+
+ 2000
+
+
+
+
+
+ 1
+
+
+ 2000
+
+
+
+
+
+ 1
+
+
+ 2000
+
+
+
+
+
+ 1
+
+
+ 20000
+
+
+
+
\ No newline at end of file
diff --git a/grails-app/controllers/au/org/ala/biocollect/AclFilterInterceptor.groovy b/grails-app/controllers/au/org/ala/biocollect/AclFilterInterceptor.groovy
index f01b70a42..2769fe5d9 100644
--- a/grails-app/controllers/au/org/ala/biocollect/AclFilterInterceptor.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/AclFilterInterceptor.groovy
@@ -3,12 +3,14 @@ package au.org.ala.biocollect
import au.org.ala.biocollect.merit.PreAuthorise
import au.org.ala.biocollect.merit.ProjectController
import au.org.ala.biocollect.merit.RoleService
+import au.org.ala.ecodata.forms.UserInfoService
import grails.converters.JSON
import org.springframework.http.HttpStatus
class AclFilterInterceptor {
int order = 3
def userService, projectService, roleService
+ UserInfoService userInfoService
def roles = []
@@ -21,6 +23,8 @@ class AclFilterInterceptor {
boolean before() {
+ userInfoService.setCurrentUser()
+
if (!controllerName)
return true
def controller = grailsApplication.getArtefactByLogicalPropertyName("Controller", controllerName)
@@ -38,7 +42,7 @@ class AclFilterInterceptor {
}
def roles = roleService.getAugmentedRoles()
- def userId = userService.getCurrentUserId(request)
+ def userId = userService.getCurrentUserId()
def projectId = params.projectId
if(!projectId){
@@ -205,6 +209,6 @@ class AclFilterInterceptor {
}
void afterView() {
- // no-op
+ userInfoService.clearCurrentUser()
}
}
diff --git a/grails-app/controllers/au/org/ala/biocollect/BioActivityController.groovy b/grails-app/controllers/au/org/ala/biocollect/BioActivityController.groovy
index 12fb36b82..bd8f563c5 100644
--- a/grails-app/controllers/au/org/ala/biocollect/BioActivityController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/BioActivityController.groovy
@@ -149,7 +149,7 @@ class BioActivityController {
log.debug("projectId = ${projectId}")
log.debug((postBody as JSON).toString())
- String userId = userService.getCurrentUserId(request)
+ String userId = userService.getCurrentUserId()
if (!userId) {
flash.message = "Access denied: User has not been authenticated."
response.status = 401
@@ -341,7 +341,7 @@ class BioActivityController {
private def addActivity(String id, boolean mobile = false) {
- String userId = userService.getCurrentUserId(request)
+ String userId = userService.getCurrentUserId()
Map pActivity = projectActivityService.get(id, "all")
String projectId = pActivity?.projectId
String type = pActivity?.pActivityFormName
@@ -378,7 +378,7 @@ class BioActivityController {
}
private editActivity(String id, boolean mobile = false){
- String userId = userService.getCurrentUserId(request)
+ String userId = userService.getCurrentUserId()
def activity = activityService.get(id)
String projectId = activity?.projectId
def model = [:]
@@ -463,7 +463,7 @@ class BioActivityController {
@Path("/ws/bioactivity/delete/{id}")
def delete(String id) {
def activity = activityService.get(id)
- String userId = userService.getCurrentUserId(request)
+ String userId = userService.getCurrentUserId()
Map result
@@ -528,7 +528,7 @@ class BioActivityController {
* @return
*/
def index(String id) {
- String userId = userService.getCurrentUserId(request)
+ String userId = userService.getCurrentUserId()
def activity = activityService.get(id, params?.version, userId, true)
if (activity.error){
redirect(controller: "error", action:'response404', params: [status: 404, errMsg: activity.error])
@@ -768,7 +768,7 @@ class BioActivityController {
private GrailsParameterMap constructDefaultSearchParams(Map params) {
GrailsParameterMap queryParams = new GrailsParameterMap([:], request)
Map parsed = commonService.parseParams(params)
- parsed.userId = userService.getCurrentUserId(parsed.mobile ? request : null)
+ parsed.userId = userService.getCurrentUserId()
parsed.each { key, value ->
if (value != null && value) {
@@ -1494,7 +1494,7 @@ class BioActivityController {
)
@Path("ws/bioactivity/data/{id}")
def getOutputForActivity(String id){
- String userId = userService.getCurrentUserId(request)
+ String userId = userService.getCurrentUserId()
def activity = activityService.get(id)
String projectId = activity?.projectId
def model = [:]
@@ -1578,7 +1578,7 @@ class BioActivityController {
)
@Path("ws/bioactivity/model/{id}")
def getActivityModel(String id){
- String userId = userService.getCurrentUserId(request)
+ String userId = userService.getCurrentUserId()
Map model = [:]
if(userId){
diff --git a/grails-app/controllers/au/org/ala/biocollect/CommentController.groovy b/grails-app/controllers/au/org/ala/biocollect/CommentController.groovy
index c8e73070d..c10ad0e2d 100644
--- a/grails-app/controllers/au/org/ala/biocollect/CommentController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/CommentController.groovy
@@ -2,21 +2,22 @@ package au.org.ala.biocollect
import au.org.ala.biocollect.merit.BaseController
import au.org.ala.biocollect.merit.CommonService
-import au.org.ala.web.AuthService
+import au.org.ala.biocollect.merit.UserService
import au.org.ala.web.NoSSO
import au.org.ala.web.SSO
import static org.apache.http.HttpStatus.SC_BAD_REQUEST
+
@SSO
class CommentController extends BaseController {
CommonService commonService
CommentService commentService
- AuthService authService
+ UserService userService
def create() {
Map json = commonService.parseParams(params)
- json.userId = authService.getUserId()
+ json.userId = userService.getCurrentUserId()
if (!json.userId|| !json.entityId || !json.entityType || !json.text){
response.sendError(SC_BAD_REQUEST, 'Missing userId, text, entityId and/or entityType')
} else {
@@ -28,7 +29,7 @@ class CommentController extends BaseController {
def update() {
def json = commonService.parseParams(params);
- json.userId = authService.getUserId()
+ json.userId = userService.getCurrentUserId()
if (!json.userId|| !json.entityId || !json.entityType || !json.text){
response.sendError(SC_BAD_REQUEST, 'Missing userId, text, entityId and/or entityType')
} else if (json) {
@@ -39,7 +40,7 @@ class CommentController extends BaseController {
def delete() {
def json = commonService.parseParams(params);
- json.userId = authService.getUserId()
+ json.userId = userService.getCurrentUserId()
if (!json.id || !json.userId){
response.sendError(SC_BAD_REQUEST, 'Missing userId and/or comment id')
} else if (json) {
diff --git a/grails-app/controllers/au/org/ala/biocollect/OrganisationController.groovy b/grails-app/controllers/au/org/ala/biocollect/OrganisationController.groovy
index 9489748b1..46e95d42b 100644
--- a/grails-app/controllers/au/org/ala/biocollect/OrganisationController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/OrganisationController.groovy
@@ -1,10 +1,9 @@
package au.org.ala.biocollect
import au.org.ala.biocollect.merit.RoleService
-import au.org.ala.web.AuthService
-import grails.converters.JSON
-import au.org.ala.web.SSO
import au.org.ala.web.NoSSO
+import au.org.ala.web.SSO
+import grails.converters.JSON
/**
* Processes requests relating to organisations
*/
@@ -14,7 +13,6 @@ class OrganisationController {
static allowedMethods = [ajaxDelete: "POST", delete: "POST", ajaxUpdate: "POST"]
def organisationService, searchService, documentService, userService, roleService, commonService, webService
- AuthService authService
// Simply forwards to the list view
@NoSSO
@@ -203,7 +201,7 @@ class OrganisationController {
* @return
*/
def searchMyOrg(Integer offset, Integer max, String searchTerm, String sort) {
- String userId = authService.getUserId()
+ String userId = userService.getCurrentUserId()
render organisationService.search(offset, max, searchTerm, sort, userId) as JSON
}
diff --git a/grails-app/controllers/au/org/ala/biocollect/RecordController.groovy b/grails-app/controllers/au/org/ala/biocollect/RecordController.groovy
index 6de8eb5a1..541d9bacb 100644
--- a/grails-app/controllers/au/org/ala/biocollect/RecordController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/RecordController.groovy
@@ -41,7 +41,7 @@ class RecordController {
}
def listProjectActivityAndUserRecords(String id) {
- def userId = userService.getCurrentUserId(request)
+ def userId = userService.getCurrentUserId()
if (!userId) {
return forbidden("Sorry mate, can't help you.")
}
diff --git a/grails-app/controllers/au/org/ala/biocollect/merit/AdminController.groovy b/grails-app/controllers/au/org/ala/biocollect/merit/AdminController.groovy
index 038f5d42f..fb2b73bc7 100644
--- a/grails-app/controllers/au/org/ala/biocollect/merit/AdminController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/merit/AdminController.groovy
@@ -2,6 +2,8 @@ package au.org.ala.biocollect.merit
import au.org.ala.biocollect.merit.hub.HubSettings
import grails.converters.JSON
+import org.grails.plugin.cache.GrailsCacheManager
+
//import grails.plugin.cache.CacheEvict
import org.springframework.cache.annotation.CacheEvict
import grails.util.Environment
@@ -17,7 +19,6 @@ class AdminController {
def cacheService
def metadataService
- def authService
def projectService
def importService
def adminService
@@ -29,8 +30,10 @@ class AdminController {
def documentService
def projectActivityService
def webService
+ UserService userService
grails.core.GrailsApplication grailsApplication
def roleService
+ GrailsCacheManager grailsCacheManager
def index() {}
@@ -44,7 +47,7 @@ class AdminController {
* @return
*/
def users() {
- def user = authService.userDetails()
+ def user = userService.getUser()
def projects = projectService.list(true)
def roles = metadataService.getAccessLevels().collect {
it.name
@@ -60,7 +63,7 @@ class AdminController {
@PreAuthorise(accessLevel = 'alaAdmin', redirectController = "admin")
def bulkLoadUserPermissions() {
- def user = authService.userDetails()
+ def user = userService.getUser()
[user:user]
}
@@ -76,7 +79,7 @@ class AdminController {
@PreAuthorise(accessLevel = 'alaAdmin', redirectController = "admin")
def uploadUserPermissionsCSV() {
- def user = authService.userDetails()
+ def user = userService.getUser()
def results
@@ -516,4 +519,18 @@ class AdminController {
render text: [message:'Species rematch initiated.'] as JSON, contentType: 'application/json'
}
+ @PreAuthorise(accessLevel = 'alaAdmin', redirectController = "admin")
+ def cacheManagement() {
+ [cacheRegions:grailsCacheManager.getCacheNames()]
+ }
+
+ @PreAuthorise(accessLevel = 'alaAdmin', redirectController = "admin")
+ def clearCache() {
+ if (params.cache) {
+ grailsCacheManager.getCache(params.cache).clear()
+ }
+
+ redirect action: 'cacheManagement'
+ }
+
}
diff --git a/grails-app/controllers/au/org/ala/biocollect/merit/ImageController.groovy b/grails-app/controllers/au/org/ala/biocollect/merit/ImageController.groovy
index 5d77588a3..a467c8982 100644
--- a/grails-app/controllers/au/org/ala/biocollect/merit/ImageController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/merit/ImageController.groovy
@@ -212,7 +212,7 @@ class ImageController {
@Path("ws/attachment/upload")
@NoSSO
def upload() {
- def user = userService.getCurrentUserId(request)
+ def user = userService.getCurrentUserId()
def result = []
if (request.respondsTo('getFile') && user) {
diff --git a/grails-app/controllers/au/org/ala/biocollect/merit/ProjectController.groovy b/grails-app/controllers/au/org/ala/biocollect/merit/ProjectController.groovy
index 9889fbd8f..fe2a2f406 100644
--- a/grails-app/controllers/au/org/ala/biocollect/merit/ProjectController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/merit/ProjectController.groovy
@@ -10,6 +10,7 @@ import au.org.ala.plugins.openapi.Path
import au.org.ala.web.AuthService
import au.org.ala.web.NoSSO
import au.org.ala.web.SSO
+import au.org.ala.web.UserDetails
import grails.converters.JSON
import grails.web.servlet.mvc.GrailsParameterMap
import io.swagger.v3.oas.annotations.Operation
@@ -1314,7 +1315,7 @@ class ProjectController {
}
def auditMessageDetails() {
- String userId = authService.getUserId()
+ String userId = userService.getCurrentUserId()
String projectId = params.projectId
String compareId= params.compareId
String skin
@@ -1342,7 +1343,7 @@ class ProjectController {
}
def getAuditMessagesForProject(){
- String userId = authService.getUserId()
+ String userId = userService.getCurrentUserId()
String projectId = params.id
Boolean isAdmin = projectService.isUserAdminForProject(userId, projectId)
if(isAdmin) {
@@ -1383,7 +1384,7 @@ class ProjectController {
Map payload = request.JSON
payload.max = payload.max ?: 10;
payload.offset = payload.offset ?: 0;
- payload.userId = authService.getUserId()
+ payload.userId = userService.getCurrentUserId()
payload.order = payload.order ?: 'DESC';
payload.sort = payload.sort ?: 'lastUpdated';
payload.fq = payload.fq ?: []
diff --git a/grails-app/controllers/au/org/ala/biocollect/merit/SiteController.groovy b/grails-app/controllers/au/org/ala/biocollect/merit/SiteController.groovy
index d88995389..de1c37ea8 100644
--- a/grails-app/controllers/au/org/ala/biocollect/merit/SiteController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/merit/SiteController.groovy
@@ -3,10 +3,10 @@ package au.org.ala.biocollect.merit
import au.org.ala.biocollect.swagger.model.SiteAjaxUpdate
import au.org.ala.biocollect.swagger.model.SiteCreateUpdateResponse
import au.org.ala.plugins.openapi.Path
-import au.org.ala.web.AuthService
import au.org.ala.web.NoSSO
import au.org.ala.web.SSO
import grails.converters.JSON
+import grails.web.servlet.mvc.GrailsParameterMap
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.enums.ParameterIn
@@ -18,7 +18,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.security.SecurityRequirement
import org.apache.commons.lang.StringUtils
import org.apache.http.HttpStatus
-import grails.web.servlet.mvc.GrailsParameterMap
+
import static javax.servlet.http.HttpServletResponse.SC_CONFLICT
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT
@@ -28,7 +28,6 @@ class SiteController {
def siteService, projectService, projectActivityService, activityService, metadataService, userService,
searchService, importService, webService
- AuthService authService
CommonService commonService
static defaultAction = "index"
@@ -131,7 +130,7 @@ class SiteController {
redirect(controller: 'home', action: 'index')
} else {
String projectIds = result.site.projects.toList().join(',')
- String userId = authService.getUserId()
+ String userId = userService.getCurrentUserId()
result.userCanEdit = projectService.isUserEditorForProjects(userId, projectIds)
result
}
@@ -544,7 +543,7 @@ class SiteController {
@NoSSO
def ajaxUpdate(String id) {
def result = [:]
- String userId = userService.getCurrentUserId(request)
+ String userId = userService.getCurrentUserId()
def postBody = request.JSON
Boolean isCreateSiteRequest = !id
@@ -735,7 +734,7 @@ class SiteController {
List results
if (params.id) {
GrailsParameterMap mParams = new GrailsParameterMap(commonService.parseParams(params), request);
- mParams.userId = authService.getUserId()
+ mParams.userId = userService.getCurrentUserId()
try {
results = siteService.getImages(mParams)
render(text: results as JSON, contentType: 'application/json')
@@ -760,7 +759,7 @@ class SiteController {
Map results
if (params.siteId && params.poiId) {
GrailsParameterMap mParams = new GrailsParameterMap(commonService.parseParams(params), request);
- mParams.userId = authService.getUserId()
+ mParams.userId = userService.getCurrentUserId()
try {
results = siteService.getPoiImages(mParams)
render(text: results as JSON, contentType: 'application/json')
diff --git a/grails-app/controllers/au/org/ala/biocollect/merit/UserController.groovy b/grails-app/controllers/au/org/ala/biocollect/merit/UserController.groovy
index 6b9200f56..0e0048c71 100644
--- a/grails-app/controllers/au/org/ala/biocollect/merit/UserController.groovy
+++ b/grails-app/controllers/au/org/ala/biocollect/merit/UserController.groovy
@@ -7,7 +7,7 @@ import au.org.ala.web.SSO
*/
@SSO
class UserController {
- def userService, authService, projectService, organisationService
+ def userService, projectService, organisationService
/**
* Default view for user controller - show user dashboard page.
@@ -62,7 +62,7 @@ class UserController {
String userId = params.userId
String projectId = params.entityId
String role = params.role
- def adminUser = authService.userDetails()
+ def adminUser = userService.getUser()
if (adminUser && userId && projectId && role) {
if (role == 'caseManager' && !userService.userIsSiteAdmin()) {
@@ -81,7 +81,7 @@ class UserController {
String userId = params.userId
String organisationId = params.entityId
String role = params.role
- def adminUser = authService.userDetails()
+ def adminUser = userService.getUser()
if (adminUser && userId && organisationId && role) {
if (role == 'caseManager' && !userService.userIsSiteAdmin()) {
@@ -105,7 +105,7 @@ class UserController {
String userId = params.userId
String role = params.role
String projectId = params.entityId
- def adminUser = authService.userDetails()
+ def adminUser = userService.getUser()
if (adminUser && projectId && role && userId) {
if (projectService.isUserAdminForProject(adminUser.userId, projectId)) {
@@ -127,7 +127,7 @@ class UserController {
String userId = params.userId
String role = params.role
String organisationId = params.entityId
- def adminUser = authService.userDetails()
+ def adminUser = userService.getUser()
if (adminUser && organisationId && role && userId) {
if (organisationService.isUserAdminForOrganisation(organisationId)) {
@@ -148,7 +148,7 @@ class UserController {
def viewPermissionsForUserId() {
String userId = params.userId
- if (authService.userDetails() && (authService.userInRole(grailsApplication.config.security.cas.alaAdminRole) || authService.userInRole(grailsApplication.config.security.cas.officerRole)) && userId) {
+ if (userService.getUser() && (userService.userInRole(grailsApplication.config.security.cas.alaAdminRole) || userService.userInRole(grailsApplication.config.security.cas.officerRole)) && userId) {
render userService.getProjectsForUserId(userId) as JSON
} else if (!userId) {
render status:400, text: 'Required params not provided: userId, role, projectId'
diff --git a/grails-app/services/au/org/ala/biocollect/CommentService.groovy b/grails-app/services/au/org/ala/biocollect/CommentService.groovy
index 876d2e70f..64dab97c1 100644
--- a/grails-app/services/au/org/ala/biocollect/CommentService.groovy
+++ b/grails-app/services/au/org/ala/biocollect/CommentService.groovy
@@ -5,7 +5,6 @@ class CommentService {
def webService
def grailsApplication
def userService
- def authService
def addComment(data) {
webService.doPost(grailsApplication.config.ecodata.service.url + "/comment",data)
@@ -29,7 +28,7 @@ class CommentService {
Boolean admin = userService.userIsAlaAdmin();
def response = webService.doGet(grailsApplication.config.ecodata.service.url + "/comment", data)
if(response?.resp){
- response.resp['userId'] = authService.getUserId()
+ response.resp['userId'] = userService.getCurrentUserId()
Map privilege = webService.doGet(grailsApplication.config.ecodata.service.url + "/comment/canUserEditOrDeleteComment",
[userId:response.resp['userId'], entityId:data['entityId'], entityType: data['entityType']] ).resp;
// this is used by knockout to decide if edit/delete should be shown.
diff --git a/grails-app/services/au/org/ala/biocollect/ProjectActivityService.groovy b/grails-app/services/au/org/ala/biocollect/ProjectActivityService.groovy
index b29567ae4..bfb276626 100644
--- a/grails-app/services/au/org/ala/biocollect/ProjectActivityService.groovy
+++ b/grails-app/services/au/org/ala/biocollect/ProjectActivityService.groovy
@@ -2,7 +2,6 @@ package au.org.ala.biocollect
import au.org.ala.biocollect.merit.*
import au.org.ala.biocollect.merit.hub.HubSettings
-import au.org.ala.web.AuthService
import org.springframework.context.MessageSource
import java.nio.file.Files
@@ -33,7 +32,6 @@ class ProjectActivityService {
MetadataService metadataService
MessageSource messageSource
UtilService utilService
- AuthService authService
CacheService cacheService
SettingService settingService
diff --git a/grails-app/services/au/org/ala/biocollect/merit/ProjectService.groovy b/grails-app/services/au/org/ala/biocollect/merit/ProjectService.groovy
index 416c89603..81422ff75 100644
--- a/grails-app/services/au/org/ala/biocollect/merit/ProjectService.groovy
+++ b/grails-app/services/au/org/ala/biocollect/merit/ProjectService.groovy
@@ -5,6 +5,7 @@ import au.org.ala.biocollect.OrganisationService
import au.org.ala.biocollect.merit.hub.HubSettings
import grails.converters.JSON
import org.springframework.context.MessageSource
+import au.org.ala.web.UserDetails
class ProjectService {
@@ -663,10 +664,10 @@ class ProjectService {
}
- public JSON userProjects(UserDetails user) {
+ JSON userProjects(UserDetails user) {
if (user) {
- def projects = userService.getProjectsForUserId(8443)
- def starredProjects = userService.getStarredProjectsForUserId(8443)
+ def projects = userService.getProjectsForUserId(user?.userId)
+ def starredProjects = userService.getStarredProjectsForUserId(user?.userId)
['active': projects, 'starred': starredProjects] as JSON;
} else {
[:] as JSON
diff --git a/grails-app/services/au/org/ala/biocollect/merit/UserService.groovy b/grails-app/services/au/org/ala/biocollect/merit/UserService.groovy
index 7c9c5dc9e..2a1ac8f9e 100644
--- a/grails-app/services/au/org/ala/biocollect/merit/UserService.groovy
+++ b/grails-app/services/au/org/ala/biocollect/merit/UserService.groovy
@@ -3,6 +3,7 @@ package au.org.ala.biocollect.merit
import au.org.ala.biocollect.merit.hub.HubSettings
import au.org.ala.ecodata.forms.UserInfoService
import au.org.ala.userdetails.UserDetailsFromIdListResponse
+import au.org.ala.web.UserDetails
class UserService {
def grailsApplication, authService, webService
@@ -28,19 +29,12 @@ class UserService {
getUser()?.displayName?:""
}
- def getCurrentUserId(request = null) {
- userInfoService.getCurrentUser()?.userId
+ def getCurrentUserId() {
+ getUser()?.userId
}
- public UserDetails getUser() {
- def u = authService.userDetails()
- def user
-
- if (u?.userId) {
- user = new UserDetails(u.getDisplayName(), u.email, u.userId)
- }
-
- return user
+ UserDetails getUser() {
+ userInfoService.getCurrentUser()
}
/**
@@ -67,23 +61,23 @@ class UserService {
}
def userInRole(role) {
- authService.userInRole(role)
+ userInfoService.getCurrentUser()?.hasRole(role)
}
def userIsSiteAdmin() {
- authService.userInRole(grailsApplication.config.security.cas.officerRole) || authService.userInRole(grailsApplication.config.security.cas.adminRole) || authService.userInRole(grailsApplication.config.security.cas.alaAdminRole)
+ userInRole(grailsApplication.config.security.cas.officerRole) || userInRole(grailsApplication.config.security.cas.adminRole) || userInRole(grailsApplication.config.security.cas.alaAdminRole)
}
Boolean userIsAlaAdmin() {
- authService.userInRole(grailsApplication.config.security.cas.alaAdminRole)
+ userInRole(grailsApplication.config.security.cas.alaAdminRole)
}
def userIsAlaOrFcAdmin() {
- authService.userInRole(grailsApplication.config.security.cas.adminRole) || authService.userInRole(grailsApplication.config.security.cas.alaAdminRole)
+ userInRole(grailsApplication.config.security.cas.adminRole) || userInRole(grailsApplication.config.security.cas.alaAdminRole)
}
def userHasReadOnlyAccess() {
- authService.userInRole(grailsApplication.config.security.cas.readOnlyOfficerRole)
+ userInRole(grailsApplication.config.security.cas.readOnlyOfficerRole)
}
def getRecentEditsForUserId(userId) {
diff --git a/grails-app/services/au/org/ala/biocollect/merit/WebService.groovy b/grails-app/services/au/org/ala/biocollect/merit/WebService.groovy
index 4baab4571..4beb1453c 100644
--- a/grails-app/services/au/org/ala/biocollect/merit/WebService.groovy
+++ b/grails-app/services/au/org/ala/biocollect/merit/WebService.groovy
@@ -25,7 +25,7 @@ import org.grails.web.converters.exceptions.ConverterException
import grails.web.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.web.multipart.MultipartFile
-
+import au.org.ala.ws.tokens.TokenService
import javax.servlet.http.Cookie
import javax.servlet.http.HttpServletResponse
import java.nio.charset.StandardCharsets
@@ -43,6 +43,7 @@ class WebService {
}
def grailsApplication
+ TokenService tokenService
def get(String url, boolean includeUserId) {
def conn = null
@@ -70,13 +71,13 @@ class WebService {
URLConnection conn = new URL(url).openConnection()
def readTimeout = timeout?:defaultTimeout()
- conn.setConnectTimeout(grailsApplication.config.webservice.connectTimeout as int)
+ conn.setConnectTimeout(grailsApplication.config.getProperty("webservice.connectTimeout", Integer))
conn.setReadTimeout(readTimeout)
addHubUrlPath(conn)
if (includeUserId) {
def user = getUserService().getUser()
if (user) {
- conn.setRequestProperty(grailsApplication.config.app.http.header.userId, user.userId)
+ conn.setRequestProperty(grailsApplication.config.getProperty("app.http.header.userId", String), user.userId)
}
}
conn
@@ -85,7 +86,7 @@ class WebService {
URLConnection addHubUrlPath (URLConnection conn) {
def hostName = grailsApplication.config.getProperty('grails.serverURL', String)
if (hostName) {
- conn.setRequestProperty(grailsApplication.config.app.http.header.hostName, hostName)
+ conn.setRequestProperty(grailsApplication.config.getProperty("app.http.header.hostName", String), hostName)
}
conn
@@ -94,7 +95,7 @@ class WebService {
Map addHubUrlPath (Map headers) {
def hostName = grailsApplication.config.getProperty('grails.serverURL', String)
if (hostName) {
- headers[grailsApplication.config.app.http.header.hostName] = hostName
+ headers[grailsApplication.config.getProperty("app.http.header.hostName", String)] = hostName
}
headers
@@ -112,7 +113,7 @@ class WebService {
conn.setReadTimeout(readTimeout)
if (includeApiKey) {
- conn.setRequestProperty("Authorization", grailsApplication.config.api_key);
+ conn.setRequestProperty("Authorization", grailsApplication.config.getProperty("api_key"))
}
def headers = [HttpHeaders.CONTENT_DISPOSITION, HttpHeaders.CACHE_CONTROL, HttpHeaders.EXPIRES, HttpHeaders.LAST_MODIFIED, HttpHeaders.ETAG]
@@ -153,7 +154,7 @@ class WebService {
conn.setDoOutput ( true );
if (includeApiKey) {
- conn.setRequestProperty("Authorization", grailsApplication.config.api_key);
+ conn.setRequestProperty("Authorization", grailsApplication.config.getProperty("api_key"))
}
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream(), charEncoding)
@@ -181,13 +182,17 @@ class WebService {
def get(String url) {
return get(url, true)
}
+
+ String getAuthHeader() {
+ tokenService.getAuthToken(false).toAuthorizationHeader()
+ }
def getJson(String url, Integer timeout = null, boolean includeApiKey = false, boolean includeUserId = true) {
def conn = null
try {
conn = configureConnection(url, includeUserId, timeout)
if (includeApiKey) {
- conn.setRequestProperty("Authorization", grailsApplication.config.api_key);
+ conn.setRequestProperty("Authorization", grailsApplication.config.getProperty("api_key"))
}
conn.setRequestProperty(ACCEPT, MediaType.APPLICATION_JSON_VALUE)
def json = responseText(conn)
@@ -247,7 +252,7 @@ class WebService {
conn.setRequestMethod("POST")
conn.setDoOutput(true)
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- conn.setRequestProperty("Authorization", grailsApplication.config.api_key);
+ conn.setRequestProperty("Authorization", grailsApplication.config.getProperty("api_key"))
addHubUrlPath(conn)
def user = getUserService().getUser()
@@ -282,8 +287,8 @@ class WebService {
try {
conn = new URL(url).openConnection()
conn.setDoOutput(true)
- conn.setRequestProperty("Content-Type", "application/json;charset=${charEncoding}");
- conn.setRequestProperty("Authorization", grailsApplication.config.api_key);
+ conn.setRequestProperty("Content-Type", "application/json;charset=${charEncoding}")
+ conn.setRequestProperty("Authorization", grailsApplication.config.getProperty("api_key"))
addHubUrlPath(conn)
def user = getUserService().getUser()
@@ -318,7 +323,7 @@ class WebService {
conn.setRequestMethod("PUT")
conn.setDoOutput(true)
conn.setRequestProperty("Content-Type", "application/json;charset=${charEncoding}");
- conn.setRequestProperty("Authorization", grailsApplication.config.api_key);
+ conn.setRequestProperty("Authorization", grailsApplication.config.getProperty("api_key"))
addHubUrlPath(conn)
def user = getUserService().getUser()
@@ -364,7 +369,7 @@ class WebService {
conn.setDoOutput(true)
conn.setRequestMethod("GET")
conn.setRequestProperty("Content-Type", "${APPLICATION_JSON};charset=${StandardCharsets.UTF_8.toString()}");
- conn.setRequestProperty("Authorization", grailsApplication.config.api_key);
+ conn.setRequestProperty("Authorization", grailsApplication.config.getProperty("api_key"))
addHubUrlPath(conn)
def user = getUserService().getUser()
@@ -393,7 +398,7 @@ class WebService {
try {
conn = new URL(url).openConnection()
conn.setRequestMethod("DELETE")
- conn.setRequestProperty("Authorization", grailsApplication.config.api_key);
+ conn.setRequestProperty("Authorization", grailsApplication.config.getProperty("api_key"))
addHubUrlPath(conn)
def user = getUserService().getUser()
@@ -461,7 +466,7 @@ class WebService {
}
addHubUrlPath(headers)
- headers.'Authorization' = grailsApplication.config.api_key
+ headers."Authorization" = grailsApplication.config.getProperty("api_key")
if (user) {
headers[grailsApplication.config.app.http.header.userId] = user.userId
}
diff --git a/grails-app/taglib/au/org/ala/biocollect/TemplateTagLib.groovy b/grails-app/taglib/au/org/ala/biocollect/TemplateTagLib.groovy
index b4a12175b..d60a4f04f 100644
--- a/grails-app/taglib/au/org/ala/biocollect/TemplateTagLib.groovy
+++ b/grails-app/taglib/au/org/ala/biocollect/TemplateTagLib.groovy
@@ -356,7 +356,7 @@ class TemplateTagLib {
case 'biocacheexplorer':
String fq = ''
if(request.forwardURI?.contains('/bioActivity/myProjectRecords')){
- fq = "&fq=alau_user_id:${userService.getCurrentUserId(request)}";
+ fq = "&fq=alau_user_id:${userService.getCurrentUserId()}";
}
url = grailsApplication.config.biocache.baseURL + '/occurrences/search?q=*:*&fq=(data_resource_uid:dr364)' + fq
@@ -402,6 +402,6 @@ class TemplateTagLib {
}
private String getCurrentURL(Map hubConfig){
- grailsApplication.config.getProperty("grails.serverURL") + request.forwardURI + "?hub=" + hubConfig.urlPath
+ g.createLink(absolute: true, uri: '/').toString()
}
}
diff --git a/grails-app/views/admin/cacheManagement.gsp b/grails-app/views/admin/cacheManagement.gsp
new file mode 100644
index 000000000..a3f43b0bf
--- /dev/null
+++ b/grails-app/views/admin/cacheManagement.gsp
@@ -0,0 +1,23 @@
+
+
+
+
+ Cache Management | Admin | Data capture | Atlas of Living Australia
+
+
+
+
+Caches
+Caches Management
+
+
+
+
diff --git a/grails-app/views/layouts/adminLayout.gsp b/grails-app/views/layouts/adminLayout.gsp
index bb2cfff0f..7cd24e29b 100644
--- a/grails-app/views/layouts/adminLayout.gsp
+++ b/grails-app/views/layouts/adminLayout.gsp
@@ -27,7 +27,7 @@
-
+
diff --git a/karma.conf.js b/karma.conf.js
index b38a327ff..8cf246d5f 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -41,7 +41,9 @@ module.exports = function (config) {
'grails-app/assets/javascripts/MapUtilities.js',
'https://cdn.jsdelivr.net/gh/AtlasOfLivingAustralia/ecodata-client-plugin/grails-app/assets/vendor/select2/4.0.3/js/select2.full.js',
'https://cdn.jsdelivr.net/gh/AtlasOfLivingAustralia/ecodata-client-plugin/grails-app/assets/vendor/typeahead/0.11.1/bloodhound.js',
+ 'https://cdn.jsdelivr.net/gh/AtlasOfLivingAustralia/ecodata-client-plugin/grails-app/assets/vendor/expr-eval/2.0.2/bundle.js',
'https://cdn.jsdelivr.net/gh/AtlasOfLivingAustralia/ecodata-client-plugin/grails-app/assets/javascripts/speciesModel.js',
+ 'https://cdn.jsdelivr.net/gh/AtlasOfLivingAustralia/ecodata-client-plugin/grails-app/assets/javascripts/forms.js',
'grails-app/assets/javascripts/projectActivityInfo.js',
'grails-app/assets/javascripts/projectActivity.js',
'grails-app/assets/javascripts/projectActivities.js',
diff --git a/package-lock.json b/package-lock.json
index ec2b6e796..8f705dc1e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
"version": "6.0",
"devDependencies": {
"@metahub/karma-jasmine-jquery": "^2.0.1",
- "chromedriver": "^110.0.0",
+ "chromedriver": "^117.0.3",
"jasmine-core": "^3.5.0",
"jasmine-jquery": "^2.0.0",
"jquery": "^3.4.1",
@@ -221,9 +221,9 @@
"dev": true
},
"node_modules/@types/yauzl": {
- "version": "2.9.2",
- "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz",
- "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
"dev": true,
"optional": true,
"dependencies": {
@@ -353,9 +353,9 @@
"dev": true
},
"node_modules/axios": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz",
- "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
+ "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.0",
@@ -448,7 +448,7 @@
"node_modules/buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"dev": true,
"engines": {
"node": "*"
@@ -561,15 +561,15 @@
}
},
"node_modules/chromedriver": {
- "version": "110.0.0",
- "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-110.0.0.tgz",
- "integrity": "sha512-Le6q8xrA/3fAt+g8qiN0YjsYxINIhQMC6wj9X3W5L77uN4NspEzklDrqYNwBcEVn7PcAEJ73nLlS7mTyZRspHA==",
+ "version": "117.0.3",
+ "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-117.0.3.tgz",
+ "integrity": "sha512-c2rk2eGK5zZFBJMdviUlAJfQEBuPNIKfal4+rTFVYAmrWbMPYAqPozB+rIkc1lDP/Ryw44lPiqKglrI01ILhTQ==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"@testim/chrome-version": "^1.1.3",
- "axios": "^1.2.1",
- "compare-versions": "^5.0.1",
+ "axios": "^1.4.0",
+ "compare-versions": "^6.0.0",
"extract-zip": "^2.0.1",
"https-proxy-agent": "^5.0.1",
"proxy-from-env": "^1.1.0",
@@ -579,7 +579,7 @@
"chromedriver": "bin/chromedriver"
},
"engines": {
- "node": ">=14"
+ "node": ">=18"
}
},
"node_modules/cliui": {
@@ -628,9 +628,9 @@
"optional": true
},
"node_modules/compare-versions": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz",
- "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz",
+ "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==",
"dev": true
},
"node_modules/concat-map": {
@@ -1050,7 +1050,7 @@
"node_modules/fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
- "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
"dev": true,
"dependencies": {
"pend": "~1.2.0"
@@ -1467,12 +1467,12 @@
"dev": true
},
"node_modules/ip-regex": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
- "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
+ "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
"dev": true,
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/is-arrayish": {
@@ -1566,14 +1566,14 @@
}
},
"node_modules/is2": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.1.tgz",
- "integrity": "sha512-+WaJvnaA7aJySz2q/8sLjMb2Mw14KTplHmSwcSpZ/fWJPkUmqw3YTzSWbPJ7OAwRvdYTWF2Wg+yYJ1AdP5Z8CA==",
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz",
+ "integrity": "sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==",
"dev": true,
"dependencies": {
"deep-is": "^0.1.3",
- "ip-regex": "^2.1.0",
- "is-url": "^1.2.2"
+ "ip-regex": "^4.1.0",
+ "is-url": "^1.2.4"
},
"engines": {
"node": ">=v0.10.0"
@@ -2410,7 +2410,7 @@
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
- "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
"dev": true
},
"node_modules/picomatch": {
@@ -2922,23 +2922,30 @@
}
},
"node_modules/tcp-port-used": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.1.tgz",
- "integrity": "sha512-rwi5xJeU6utXoEIiMvVBMc9eJ2/ofzB+7nLOdnZuFTmNCLqRiQh2sMG9MqCxHU/69VC/Fwp5dV9306Qd54ll1Q==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
+ "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
"dev": true,
"dependencies": {
- "debug": "4.1.0",
- "is2": "2.0.1"
+ "debug": "4.3.1",
+ "is2": "^2.0.6"
}
},
"node_modules/tcp-port-used/node_modules/debug": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
- "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
- "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"dependencies": {
- "ms": "^2.1.1"
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
}
},
"node_modules/tcp-port-used/node_modules/ms": {
@@ -3272,7 +3279,7 @@
"node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
- "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"dev": true,
"dependencies": {
"buffer-crc32": "~0.2.3",
@@ -3459,9 +3466,9 @@
"dev": true
},
"@types/yauzl": {
- "version": "2.9.2",
- "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz",
- "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
"dev": true,
"optional": true,
"requires": {
@@ -3564,9 +3571,9 @@
"dev": true
},
"axios": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz",
- "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
+ "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"dev": true,
"requires": {
"follow-redirects": "^1.15.0",
@@ -3645,7 +3652,7 @@
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"dev": true
},
"bytes": {
@@ -3725,14 +3732,14 @@
}
},
"chromedriver": {
- "version": "110.0.0",
- "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-110.0.0.tgz",
- "integrity": "sha512-Le6q8xrA/3fAt+g8qiN0YjsYxINIhQMC6wj9X3W5L77uN4NspEzklDrqYNwBcEVn7PcAEJ73nLlS7mTyZRspHA==",
+ "version": "117.0.3",
+ "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-117.0.3.tgz",
+ "integrity": "sha512-c2rk2eGK5zZFBJMdviUlAJfQEBuPNIKfal4+rTFVYAmrWbMPYAqPozB+rIkc1lDP/Ryw44lPiqKglrI01ILhTQ==",
"dev": true,
"requires": {
"@testim/chrome-version": "^1.1.3",
- "axios": "^1.2.1",
- "compare-versions": "^5.0.1",
+ "axios": "^1.4.0",
+ "compare-versions": "^6.0.0",
"extract-zip": "^2.0.1",
"https-proxy-agent": "^5.0.1",
"proxy-from-env": "^1.1.0",
@@ -3782,9 +3789,9 @@
"optional": true
},
"compare-versions": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz",
- "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz",
+ "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==",
"dev": true
},
"concat-map": {
@@ -4109,7 +4116,7 @@
"fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
- "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
"dev": true,
"requires": {
"pend": "~1.2.0"
@@ -4418,9 +4425,9 @@
"dev": true
},
"ip-regex": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
- "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
+ "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
"dev": true
},
"is-arrayish": {
@@ -4493,14 +4500,14 @@
"dev": true
},
"is2": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.1.tgz",
- "integrity": "sha512-+WaJvnaA7aJySz2q/8sLjMb2Mw14KTplHmSwcSpZ/fWJPkUmqw3YTzSWbPJ7OAwRvdYTWF2Wg+yYJ1AdP5Z8CA==",
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz",
+ "integrity": "sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==",
"dev": true,
"requires": {
"deep-is": "^0.1.3",
- "ip-regex": "^2.1.0",
- "is-url": "^1.2.2"
+ "ip-regex": "^4.1.0",
+ "is-url": "^1.2.4"
}
},
"isbinaryfile": {
@@ -5168,7 +5175,7 @@
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
- "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
"dev": true
},
"picomatch": {
@@ -5566,22 +5573,22 @@
}
},
"tcp-port-used": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.1.tgz",
- "integrity": "sha512-rwi5xJeU6utXoEIiMvVBMc9eJ2/ofzB+7nLOdnZuFTmNCLqRiQh2sMG9MqCxHU/69VC/Fwp5dV9306Qd54ll1Q==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
+ "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
"dev": true,
"requires": {
- "debug": "4.1.0",
- "is2": "2.0.1"
+ "debug": "4.3.1",
+ "is2": "^2.0.6"
},
"dependencies": {
"debug": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
- "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
- "ms": "^2.1.1"
+ "ms": "2.1.2"
}
},
"ms": {
@@ -5816,7 +5823,7 @@
"yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
- "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"dev": true,
"requires": {
"buffer-crc32": "~0.2.3",
diff --git a/package.json b/package.json
index 9fcde44cf..2be147585 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
},
"devDependencies": {
"@metahub/karma-jasmine-jquery": "^2.0.1",
- "chromedriver": "^110.0.0",
+ "chromedriver": "^117.0.3",
"jasmine-core": "^3.5.0",
"jasmine-jquery": "^2.0.0",
"jquery": "^3.4.1",
diff --git a/src/integration-test/groovy/au/org/ala/biocollect/AddBioActivitySpec.groovy b/src/integration-test/groovy/au/org/ala/biocollect/AddBioActivitySpec.groovy
index 39c3dd8f0..7c7614ba6 100644
--- a/src/integration-test/groovy/au/org/ala/biocollect/AddBioActivitySpec.groovy
+++ b/src/integration-test/groovy/au/org/ala/biocollect/AddBioActivitySpec.groovy
@@ -1,13 +1,10 @@
package au.org.ala.biocollect
-
import pages.AddBioActivityPage
import pages.ViewBioActivityPage
-import spock.lang.Ignore
import spock.lang.Stepwise
@Stepwise
-@Ignore
class AddBioActivitySpec extends StubbedCasSpec {
def setupSpec() {
@@ -15,7 +12,7 @@ class AddBioActivitySpec extends StubbedCasSpec {
}
def cleanupSpec() {
- logout(browser, ViewBioActivityPage)
+ logout(browser)
}
def projectId = "project_1"
@@ -23,7 +20,7 @@ class AddBioActivitySpec extends StubbedCasSpec {
def site = "site_1"
def "Add an activity"() {
-
+ setup:
loginAsUser('1', browser)
when: "go to new activity page"
diff --git a/src/integration-test/groovy/au/org/ala/biocollect/StubbedCasSpec.groovy b/src/integration-test/groovy/au/org/ala/biocollect/StubbedCasSpec.groovy
index 6771db7b6..d5eee7679 100644
--- a/src/integration-test/groovy/au/org/ala/biocollect/StubbedCasSpec.groovy
+++ b/src/integration-test/groovy/au/org/ala/biocollect/StubbedCasSpec.groovy
@@ -3,6 +3,11 @@ package au.org.ala.biocollect
import com.github.tomakehurst.wiremock.WireMockServer
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer
import geb.Browser
+import grails.converters.JSON
+import org.grails.web.converters.marshaller.json.CollectionMarshaller
+import org.grails.web.converters.marshaller.json.MapMarshaller
+import org.openqa.selenium.StaleElementReferenceException
+import org.pac4j.jwt.profile.JwtGenerator
import spock.lang.Shared
import wiremock.com.github.jknack.handlebars.EscapingStrategy
import wiremock.com.github.jknack.handlebars.Handlebars
@@ -12,7 +17,7 @@ import wiremock.com.google.common.collect.ImmutableMap
import static com.github.tomakehurst.wiremock.client.WireMock.*
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options
-
+//import com.github.tomakehurst.wiremock.WireMockServer
/**
* Supports stubbing access to CAS via wiremock.
@@ -26,30 +31,35 @@ class StubbedCasSpec extends BiocollectFunctionalTest {
@Shared WireMockServer wireMockServer
def setupSpec() {
+ if (testConfig.wiremock.embedded){
- Handlebars handlebars = new Handlebars()
- handlebars.escapingStrategy = EscapingStrategy.NOOP
+ Handlebars handlebars = new Handlebars()
+ handlebars.escapingStrategy = EscapingStrategy.NOOP
- // This is done so we can use a custom handlebars with a NOOP escaping strategy - the default escapes HTML
- // which breaks the redirect URL returned by the PDF generation stub.
- Helper noop = new Helper() {
- Object apply(Object context, Options options) throws IOException {
- return context[0]
+ // This is done so we can use a custom handlebars with a NOOP escaping strategy - the default escapes HTML
+ // which breaks the redirect URL returned by the PDF generation stub.
+ Helper noop = new Helper() {
+ Object apply(Object context, Options options) throws IOException {
+ return context[0]
+ }
}
- }
- wireMockServer = new WireMockServer(options()
- .port(testConfig.wiremock.port)
- .usingFilesUnderDirectory(getMappingsPath())
- .extensions(new ResponseTemplateTransformer(false, handlebars, ImmutableMap.of("noop", noop), null, null)))
+ wireMockServer = new WireMockServer(options()
+ .port(testConfig.wiremock.port)
+ .usingFilesUnderDirectory(getMappingsPath())
+ .extensions(new ResponseTemplateTransformer(false, handlebars, ImmutableMap.of("noop", noop), null, null)))
- wireMockServer.start()
+ wireMockServer.start()
+ }
+ JSON.registerObjectMarshaller(new MapMarshaller())
+ JSON.registerObjectMarshaller(new CollectionMarshaller())
// Configure the client
configureFor("localhost", testConfig.wiremock.port)
}
def cleanupSpec() {
- wireMockServer.stop()
+ if (testConfig.wiremock.embedded)
+ wireMockServer.stop()
}
/**
@@ -63,26 +73,45 @@ class StubbedCasSpec extends BiocollectFunctionalTest {
}
/** Presses the OK button on a displayed bootbox modal */
- def okBootbox() {
+ def okBootbox(buttonSelector = '.btn-primary') {
Thread.sleep(1000) // wait for the animation to finish
- $('.bootbox .btn-primary').each { ok ->
-
-
- waitFor 20, {
- try {
- if (ok.displayed) {
- ok.click()
- }
+ // The reason we are doing an "each" and catching exception is sometimes previous dialogs remain
+ // in scope despite being detached from the DOM and StaleElementException is thrown.
+ def backdrop = $('.modal-backdrop')
+ $('.bootbox '+buttonSelector).each { ok ->
+ try {
+ if (ok.displayed) {
+ ok.click()
}
- catch (Exception e) {
- e.printStackTrace()
- }
+ }
+ catch (Exception e) {
+ e.printStackTrace()
+ }
+ }
+ Thread.sleep(1000)
+ // Dismissing bootbox modals is intermittently unreliable, so trying a javascript fallback.
+ // The other issue here is one of the tests transitions from a page with bootbox up to a page which
+ // immediately displays a modal, so the Thread.sleep means we can actually be catching the dialog on the
+ // second page. Hence why we get the element reference at the start.
+ try {
+ if (backdrop.displayed) {
+ js.exec('$(".bootbox ' + buttonSelector + '").click();')
+ Thread.sleep(1000)
waitFor {
- $('.modal-backdrop').size() == 0
+ boolean backdropDisplayed
+ try {
+ backdropDisplayed = backdrop.displayed
+ }
+ catch (StaleElementReferenceException e) {
+ backdropDisplayed = false
+ // The backdrop was already detached from the DOM due to page transition
+ }
+ !backdropDisplayed
}
}
-
+ }
+ catch (StaleElementReferenceException e) { // Do nothing, backdrop was already detached
}
}
@@ -114,8 +143,85 @@ class StubbedCasSpec extends BiocollectFunctionalTest {
login([userId:userId, email: "user${userId}@nowhere.com", firstName:"MERIT", lastName:"User ${userId}"], browser)
}
- /** Creates a wiremock configuration to stub a user login request and return the supplied user and role information */
+ private String loggedInUser = null
+
def login(Map userDetails, Browser browser) {
+ if (loggedInUser != userDetails.userId) {
+ logout(browser)
+ }
+ oidcLogin(userDetails, browser)
+ loggedInUser = userDetails.userId
+ }
+
+ def oidcLogin(Map userDetails, Browser browser) {
+
+ // The test config isn't a normal grails config object (probably need to to into why) so getProperty doesn't work.
+ String clientId = getTestConfig().security.oidc.clientId
+ List roles = ["ROLE_USER"]
+ if (userDetails.role) {
+ roles << userDetails.role
+ }
+
+ Map idTokenClaims = [
+ at_hash:"KX-L2Fj6Z9ow-gOpYfehRA",
+ sub:userDetails.userId,
+ email_verified:true,
+ role:roles,
+ amr:"DelegatedClientAuthenticationHandler",
+ iss:"http://localhost:8018/cas/oidc",
+ preferred_username:userDetails.email,
+ given_name:userDetails.firstName,
+ family_name:userDetails.lastName,
+ client_id:clientId,
+ sid:"test_sid",
+ aud:clientId,
+ name:userDetails.firstName+" "+userDetails.lastName,
+ state:"maybe_this_matters",
+ auth_time:-1,
+ nbf:com.nimbusds.jwt.util.DateUtils.toSecondsSinceEpoch(new Date().minus(365)),
+ exp:com.nimbusds.jwt.util.DateUtils.toSecondsSinceEpoch(new Date().plus(365)),
+ iat:com.nimbusds.jwt.util.DateUtils.toSecondsSinceEpoch(new Date()),
+ jti:"id",
+ email:userDetails.email
+ ]
+ String idToken = new JwtGenerator(null).generate(idTokenClaims)
+ Map token = [:]
+ token.access_token = idToken
+ token.id_token = idToken
+ token.refresh_token = null
+ token.token_type = "bearer"
+ token.expires_in = 86400
+ token.scope = "user_defined email openid profile roles"
+
+ stubFor(post(urlPathEqualTo("/cas/oidc/oidcAccessToken"))
+ .willReturn(aResponse()
+ .withStatus(200)
+ .withHeader("Content-Type", "application/json")
+ .withBody((token as JSON).toString())
+ .withTransformers("response-template")
+ ))
+
+
+ Map profile = [
+ sub:userDetails.userId,
+ name:userDetails.firstName+" "+userDetails.lastName,
+ given_name:userDetails.firstName,
+ family_name:userDetails.lastName,
+ email:userDetails.email
+ ]
+
+ stubFor(get(urlPathEqualTo("/cas/oidc/oidcProfile"))
+ .willReturn(aResponse()
+ .withStatus(200)
+ .withHeader("Content-Type", "application/json")
+ .withBody((profile as JSON).toString())
+ ))
+
+ browser.go "${getConfig().baseUrl}login"
+ }
+
+ /** Creates a wiremock configuration to stub a user login request and return the supplied user and role information */
+ def casLogin(Map userDetails, Browser browser) {
String email = "fc-te@outlook.com"
@@ -166,14 +272,14 @@ class StubbedCasSpec extends BiocollectFunctionalTest {
.willReturn(aResponse()
.withStatus(302)
- .withHeader("Location", "{{request.requestLine.query.service}}?ticket=aticket")
+ .withHeader("Location", "{{{request.requestLine.query.service}}}?ticket=aticket")
.withHeader("Set-Cookie", "ALA-Auth=\"${email}\"; Domain=ala.org.au; Path=/; HttpOnly")
.withTransformers("response-template")))
stubFor(get(urlMatching("/cas/login\\?service=.*\\?.*"))
.willReturn(aResponse()
.withStatus(302)
- .withHeader("location", "{{request.requestLine.query.service}}&ticket=aticket")
+ .withHeader("location", "{{{request.requestLine.query.service}}}&ticket=aticket")
.withHeader("Set-Cookie", "ALA-Auth=\"${email}\"; Domain=ala.org.au; Path=/; HttpOnly")
.withTransformers("response-template")))
diff --git a/src/integration-test/groovy/pages/EntryPage.groovy b/src/integration-test/groovy/pages/EntryPage.groovy
index 15099d1f4..a4825bc06 100644
--- a/src/integration-test/groovy/pages/EntryPage.groovy
+++ b/src/integration-test/groovy/pages/EntryPage.groovy
@@ -4,7 +4,7 @@ import geb.Page
class EntryPage extends Page {
static url = ""
- static at = { title == "Project Finder | BioCollect"}
+ static at = { title == "Homepage"}
static content = {
diff --git a/src/integration-test/resources/GebConfig.groovy b/src/integration-test/resources/GebConfig.groovy
index 0ad371e34..f17c4eff0 100644
--- a/src/integration-test/resources/GebConfig.groovy
+++ b/src/integration-test/resources/GebConfig.groovy
@@ -28,7 +28,11 @@ environments {
// run as grails -Dgeb.env=chrome test-app
chrome {
- driver = { new ChromeDriver() }
+ driver = {
+ ChromeOptions options = new ChromeOptions()
+ options.addArguments("--remote-allow-origins=*")
+ new ChromeDriver(options)
+ }
}
firefox {
@@ -58,6 +62,7 @@ environments {
o.addArguments('headless')
o.addArguments("window-size=1920,1080")
o.addArguments('--disable-dev-shm-usage')
+ o.addArguments("--remote-allow-origins=*")
new ChromeDriver(o)
}
}
diff --git a/src/integration-test/resources/dataset1/loadDataSet.js b/src/integration-test/resources/dataset1/loadDataSet.js
index 9193dd856..3ecc7eb85 100644
--- a/src/integration-test/resources/dataset1/loadDataSet.js
+++ b/src/integration-test/resources/dataset1/loadDataSet.js
@@ -1,5 +1,5 @@
print("This script is expected to be executed with a working directory containing this script");
-print("Current working dir: "+pwd());
+print("Current working dir: "+process.cwd());
load('../data_common/loadAlaHub.js');
load("../data_common/insertData.js");
loadActivityForms();
diff --git a/src/integration-test/resources/wiremock/mappings/logout.json b/src/integration-test/resources/wiremock/mappings/logout.json
index 318368c21..459625288 100644
--- a/src/integration-test/resources/wiremock/mappings/logout.json
+++ b/src/integration-test/resources/wiremock/mappings/logout.json
@@ -8,7 +8,7 @@
"status": 302,
"headers": {
"Set-Cookie": "ALA-Auth=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Domain=ala.org.au; Path=/; HttpOnly",
- "Location": "{{request.query.url}}"
+ "Location": "{{{request.requestLine.query.url}}}"
}
}
}
diff --git a/src/integration-test/resources/wiremock/mappings/oidcAuthorize.json b/src/integration-test/resources/wiremock/mappings/oidcAuthorize.json
new file mode 100644
index 000000000..86c7b7986
--- /dev/null
+++ b/src/integration-test/resources/wiremock/mappings/oidcAuthorize.json
@@ -0,0 +1,15 @@
+{
+ "request": {
+ "urlPath": "/cas/oidc/oidcAuthorize",
+ "method": "GET"
+ },
+ "response": {
+ "status": 302,
+ "headers": {
+ "location": "{{{request.requestLine.query.redirect_uri}}}&state={{request.query.state}}&code=12345"
+ },
+ "transformers": [
+ "response-template"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/integration-test/resources/wiremock/mappings/oidcDiscovery.json b/src/integration-test/resources/wiremock/mappings/oidcDiscovery.json
new file mode 100644
index 000000000..b5f27fb99
--- /dev/null
+++ b/src/integration-test/resources/wiremock/mappings/oidcDiscovery.json
@@ -0,0 +1,124 @@
+{
+ "request": {
+ "urlPath": "/cas/oidc/.well-known",
+ "method": "GET"
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "content-Type": "text/json"
+ },
+ "transformers": ["response-template"],
+ "jsonBody": {
+ "issuer": "http://{{request.host}}:{{request.port}}/cas/oidc",
+ "scopes_supported": [
+ "openid",
+ "profile",
+ "email",
+ "offline_access",
+ "ala",
+ "roles",
+ "users/read",
+ "users/write",
+ "ecodata/read",
+ "ecodata/write",
+ "biocache/read",
+ "biocache/write",
+ "ala/internal"
+ ],
+ "response_types_supported": [
+ "code",
+ "token",
+ "id_token token"
+ ],
+ "subject_types_supported": [
+ "public",
+ "pairwise"
+ ],
+ "claim_types_supported": [
+ "normal"
+ ],
+ "claims_supported": [
+ "sub",
+ "name",
+ "preferred_username",
+ "family_name",
+ "given_name",
+ "profile",
+ "locale",
+ "updated_at",
+ "email",
+ "email_verified",
+ "organisation",
+ "role",
+ "authority",
+ "city",
+ "state",
+ "country",
+ "userid"
+ ],
+ "grant_types_supported": [
+ "authorization_code",
+ "password",
+ "client_credentials",
+ "refresh_token"
+ ],
+ "id_token_signing_alg_values_supported": [
+ "none"
+ ],
+ "id_token_encryption_alg_values_supported": [
+ "none"
+ ],
+ "id_token_encryption_enc_values_supported": [
+ "none"
+ ],
+ "userinfo_signing_alg_values_supported": [
+ "none"
+ ],
+ "userinfo_encryption_alg_values_supported": [
+ "none"
+ ],
+ "userinfo_encryption_enc_values_supported": [
+ "none"
+ ],
+ "request_object_signing_alg_values_supported": [
+ "none"
+ ],
+ "request_object_encryption_alg_values_supported": [
+ "none"
+ ],
+ "request_object_encryption_enc_values_supported": [
+ "none"
+ ],
+ "introspection_endpoint_auth_methods_supported": [
+ "client_secret_basic"
+ ],
+ "token_endpoint_auth_methods_supported": [
+ "client_secret_basic",
+ "client_secret_post",
+ "client_secret_jwt",
+ "private_key_jwt"
+ ],
+ "code_challenge_methods_supported": [
+ "plain",
+ "S256"
+ ],
+ "claims_parameter_supported": true,
+ "request_uri_parameter_supported": true,
+ "request_parameter_supported": true,
+ "backchannel_logout_supported": true,
+ "frontchannel_logout_supported": true,
+ "jwks_uri": "http://{{request.host}}:{{request.port}}/cas/oidc/jwks",
+ "authorization_endpoint": "http://{{request.host}}:{{request.port}}/cas/oidc/oidcAuthorize",
+ "userinfo_endpoint": "http://{{request.host}}:{{request.port}}/cas/oidc/oidcProfile",
+ "pushed_authorization_request_endpoint": "http://{{request.host}}:{{request.port}}/cas/oidc/oidcPushAuthorize",
+ "registration_endpoint": "http://{{request.host}}:{{request.port}}/cas/oidc/register",
+ "end_session_endpoint": "http://{{request.host}}:{{request.port}}/cas/oidc/oidcLogout",
+ "introspection_endpoint": "http://{{request.host}}:{{request.port}}/cas/oidc/introspect",
+ "revocation_endpoint": "http://{{request.host}}:{{request.port}}/cas/oidc/revoke",
+ "backchannel_logout_session_supported": true,
+ "frontchannel_logout_session_supported": true,
+ "token_endpoint": "http://{{request.host}}:{{request.port}}/cas/oidc/oidcAccessToken"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/groovy/au/org/ala/biocollect/merit/userDetails.groovy b/src/main/groovy/au/org/ala/biocollect/merit/userDetails.groovy
deleted file mode 100644
index dde3dfddb..000000000
--- a/src/main/groovy/au/org/ala/biocollect/merit/userDetails.groovy
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2013 Atlas of Living Australia
- * All Rights Reserved.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- */
-
-package au.org.ala.biocollect.merit
-
-/**
- * Created with IntelliJ IDEA.
- *
- * @author "Nick dos Remedios "
- */
-class UserDetails {
-
- public static final String REQUEST_USER_DETAILS_KEY = 'ecodata.request.user.details'
-
- String displayName
- String userName
- String userId
-
- public UserDetails(String displayName, String userName, String userId) {
- this.displayName = displayName
- this.userName = userName
- this.userId = userId
- }
-
- public UserDetails() {}
-
- @Override
- public String toString() {
- "[ userId: ${userId}, userName: ${userName}, displayName: ${displayName} ]"
- }
-}
\ No newline at end of file
diff --git a/src/main/java/au/org/ala/biocollect/IntegrationTestConfiguration.java b/src/main/java/au/org/ala/biocollect/IntegrationTestConfiguration.java
new file mode 100644
index 000000000..0209ff7a5
--- /dev/null
+++ b/src/main/java/au/org/ala/biocollect/IntegrationTestConfiguration.java
@@ -0,0 +1,18 @@
+package au.org.ala.biocollect;
+
+import au.org.ala.ws.security.AlaWsSecurityConfiguration;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.proc.SecurityContext;
+import org.pac4j.oidc.config.OidcConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class IntegrationTestConfiguration extends AlaWsSecurityConfiguration {
+ @Bean
+ JWKSource jwkSource(OidcConfiguration oidcConfiguration) {
+ return new ImmutableJWKSet(new JWKSet());
+ }
+}
diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/main/scripts/loadFunctionalTestData.sh b/src/main/scripts/loadFunctionalTestData.sh
index 9b83fe1f2..d5c10f993 100755
--- a/src/main/scripts/loadFunctionalTestData.sh
+++ b/src/main/scripts/loadFunctionalTestData.sh
@@ -11,7 +11,7 @@ AUTH_OPTS=
if [ "$2" ]
then
AUTH_OPTS="-u $2 -p $3"
- echo "mongo $DATABASE_NAME $AUTH_OPTS --eval " >> /tmp/blah
+ echo "mongosh $DATABASE_NAME $AUTH_OPTS --eval " >> /tmp/blah
fi
DATABASE_NAME=ecodata-functional-test
@@ -20,7 +20,7 @@ DATA_PATH=$1
cd $DATA_PATH
echo $PWD
-mongo $DATABASE_NAME $AUTH_OPTS --eval "db.dropDatabase()"
-mongo $DATABASE_NAME $AUTH_OPTS loadDataSet.js
+mongosh $DATABASE_NAME $AUTH_OPTS --eval "db.dropDatabase()"
+mongosh $DATABASE_NAME $AUTH_OPTS loadDataSet.js
diff --git a/src/main/scripts/runFunctionalTests.sh b/src/main/scripts/runFunctionalTests.sh
index 6c0f69308..141c0380a 100755
--- a/src/main/scripts/runFunctionalTests.sh
+++ b/src/main/scripts/runFunctionalTests.sh
@@ -1,6 +1,6 @@
#!/bin/bash -v
-MERIT_DIR=$PWD
+BIOCOLLECT_DIR=$PWD
GEB_ENV=$1
if [ -z $GEB_ENV ]; then
@@ -22,28 +22,40 @@ if [ ! -d $ECODATA_LOCAL_DIR ]; then
git clone https://github.com/AtlasOfLivingAustralia/ecodata.git
cd ecodata
git checkout $BRANCH
+ echo "Cloned ecodata $BRANCH into /tmp/ecodata"
else
cd $ECODATA_LOCAL_DIR
+ git checkout $BRANCH
git pull
+ echo "Updated ecodata $BRANCH in /tmp/ecodata"
fi
echo "Dropping database"
-mongo ecodata-functional-test --eval 'db.dropDatabase();'
-mongo ecodata-functional-test --eval 'db.project.count();'
+mongosh ecodata-functional-test --eval 'db.dropDatabase();'
+mongosh ecodata-functional-test --eval 'db.project.count();'
+cd "$BIOCOLLECT_DIR/src/integration-test/resources/data_common/"
+mongosh ecodata-functional-test loadAlaHub.js
+
+echo "Hosts file configuration"
+cat /etc/hosts
+cd $ECODATA_LOCAL_DIR
echo "Starting ecodata from `pwd`"
ls -la
-GRADLE_OPTS="-Xmx512m" ./gradlew bootRun --no-daemon "-Dorg.gradle.jvmargs=-Xmx512m" -Dgrails.env=meritfunctionaltest &
-sleep 120
+GRADLE_OPTS="-Xmx1g" ./gradlew bootRun "-Dorg.gradle.jvmargs=-Xmx1g" -Dgrails.env=meritfunctionaltest &
+sleep 240
-cd $MERIT_DIR
-GRADLE_OPTS="-Xmx512m" ./gradlew bootRun --no-daemon "-Dorg.gradle.jvmargs=-Xmx512m" -Dgrails.env=test -Dgrails.server.port.http=8087 &
-sleep 180
+cd $BIOCOLLECT_DIR
+echo "Starting wire mock"
+./gradlew startWireMock
+echo "Starting biocollect"
+GRADLE_OPTS="-Xmx1g" ./gradlew bootRun "-Dorg.gradle.jvmargs=-Xmx1g" -Dgrails.env=test -Dgrails.server.port.http=8087 &
+sleep 200
chmod u+x src/main/scripts/loadFunctionalTestData.sh
echo "Running functional tests"
-./gradlew integrationTest --stacktrace -Dgeb.env=$GEB_ENV
+GRADLE_OPTS="-Xmx1g" ./gradlew integrationTest "-Dorg.gradle.jvmargs=-Xmx1g" --stacktrace -Dgeb.env=$GEB_ENV
RETURN_VALUE=$?
diff --git a/src/test/groovy/au/org/ala/biocollect/merit/ProjectControllerSpec.groovy b/src/test/groovy/au/org/ala/biocollect/merit/ProjectControllerSpec.groovy
index 0ea908e1c..df867f6b9 100644
--- a/src/test/groovy/au/org/ala/biocollect/merit/ProjectControllerSpec.groovy
+++ b/src/test/groovy/au/org/ala/biocollect/merit/ProjectControllerSpec.groovy
@@ -5,6 +5,7 @@ import au.org.ala.biocollect.ProjectActivityService
import au.org.ala.biocollect.VocabService
import au.org.ala.biocollect.merit.hub.HubSettings
import au.org.ala.web.AuthService
+import au.org.ala.web.UserDetails
import grails.testing.web.controllers.ControllerUnitTest
import org.apache.http.HttpStatus
import spock.lang.Specification
@@ -59,7 +60,7 @@ class ProjectControllerSpec extends Specification implements ControllerUnitTest<
userServiceStub.getOrganisationIdsForUserId(_) >> []
userServiceStub.isProjectStarredByUser(_, _) >> [isProjectStarredByUser:true]
roleServiceStub.getRoles() >> []
- authServiceStub.getUserId() >> ''
+ userServiceStub.getCurrentUserId() >> ''
blogServiceStub.get(_, _) >> []
organisationStub.get(_) >> [organisationId: "ABC123", name: "organisation name"]
vocabServiceStub.getVocabValues() >> []
@@ -70,7 +71,7 @@ class ProjectControllerSpec extends Specification implements ControllerUnitTest<
void "creating a citizen science project should pre-populate the citizen science project type"() {
when:
- userServiceStub.getUser() >> [userId:'1234']
+ userServiceStub.getUser() >> new UserDetails(1, '', '', '', '', '1234', false, true, null)
params.citizenScience = true
def model = controller.create()
@@ -82,7 +83,7 @@ class ProjectControllerSpec extends Specification implements ControllerUnitTest<
void "creating a project should pre-populate the organisation if the user is a member of exactly one organisation"() {
when:
- userServiceStub.getUser() >> [userId:'1234']
+ userServiceStub.getUser() >> new UserDetails(1, '', '', '', '', '1234', false, true, null)
def model = controller.create()
@@ -93,7 +94,7 @@ class ProjectControllerSpec extends Specification implements ControllerUnitTest<
void "when creating a project, the current hub's default program should be assigned to the new project"() {
when:
- userServiceStub.getUser() >> [userId:'1234']
+ userServiceStub.getUser() >> new UserDetails(1, '', '', '', '', '1234', false, true, null)
SettingService.setHubConfig(new HubSettings([defaultProgram:'my program']))
def model = controller.create()
@@ -107,7 +108,7 @@ class ProjectControllerSpec extends Specification implements ControllerUnitTest<
when:
def projectId = 'project1'
- userServiceStub.getUser() >> [userId:'1234']
+ userServiceStub.getUser() >> new UserDetails(1, '', '', '', '', '1234', false, true, null)
projectServiceStub.get(projectId, _) >> [organisationId:'org1', projectId:projectId, name:'Test', projectSiteId:siteId]
params.organisationId = 'org2'
@@ -396,7 +397,7 @@ class ProjectControllerSpec extends Specification implements ControllerUnitTest<
void "get my Citizen Science Projects"() {
setup:
- userServiceStub.getUser() >> [userId:'1234', userName:"test", displayName:"test"]
+ userServiceStub.getUser() >> new UserDetails(1, 'test', 'test', 'test', 'test', '1234', false, true, null)
SettingService.setHubConfig(new HubSettings([defaultProgram:'my program', defaultFacetQuery:"isCitizenScience:true"]))
when:
@@ -407,7 +408,7 @@ class ProjectControllerSpec extends Specification implements ControllerUnitTest<
view == "/project/projectFinder"
model.user.userId == "1234"
model.user.userName == "test"
- model.user.displayName == "test"
+ model.user.displayName == "test test"
model.showTag == true
model.downloadLink == "/ws/project/search?initiator=biocollect&download=true"
model.isUserPage == true
diff --git a/src/test/groovy/au/org/ala/biocollect/merit/SiteControllerSpec.groovy b/src/test/groovy/au/org/ala/biocollect/merit/SiteControllerSpec.groovy
index ef6c4e97c..6c807d363 100644
--- a/src/test/groovy/au/org/ala/biocollect/merit/SiteControllerSpec.groovy
+++ b/src/test/groovy/au/org/ala/biocollect/merit/SiteControllerSpec.groovy
@@ -1,22 +1,22 @@
package au.org.ala.biocollect.merit
-import au.org.ala.web.AuthService
+
import grails.testing.web.controllers.ControllerUnitTest
-import org.apache.http.HttpStatus
import grails.web.servlet.mvc.GrailsParameterMap
+import org.apache.http.HttpStatus
import spock.lang.Specification
class SiteControllerSpec extends Specification implements ControllerUnitTest {
SiteService siteService = Stub(SiteService)
- AuthService authService = Stub(AuthService)
CommonService commonService = Stub(CommonService)
+ UserService userService = Stub(UserService)
def setup() {
controller.siteService = siteService
- controller.authService = authService
controller.commonService = commonService
- authService.getUserId() >> '1'
+ controller.userService = userService
+ userService.getCurrentUserId() >> '1'
}
def cleanup() {