Skip to content

Commit

Permalink
Merge pull request #178 from AtlasOfLivingAustralia/develop
Browse files Browse the repository at this point in the history
PR for 3.1.2 release
  • Loading branch information
sughics authored Jan 24, 2023
2 parents fb8286f + af02e94 commit c2bdc06
Show file tree
Hide file tree
Showing 25 changed files with 408 additions and 173 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ branches:
only:
- master
- develop
- feature/oidc
- feature/issue-175

before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ plugins {
id "com.gorylenko.gradle-git-properties" version "2.4.0-rc2"
}

version "3.1.1"

version "3.1.2-SNAPSHOT"

group "au.org.ala"

Expand Down
1 change: 1 addition & 0 deletions grails-app/conf/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ biocacheUiURL: https://biocache.ala.org.au
isPipelinesCompatible: true

ROLE_ADMIN: 'ROLE_ADMIN'
ROLE_EDITOR: 'ROLE_EDITOR'

rifcs:
excludeBounds: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
package au.org.ala.collectory


import com.opencsv.CSVReader
import grails.converters.JSON
import grails.web.JSONBuilder
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
class AdminController {

def dataLoaderService, idGeneratorService, collectoryAuthService, metadataService, activityLogService, providerGroupService
class AdminController {

def auth() {
if (!collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN) && grailsApplication.config.security.oidc.enabled.toBoolean()) {
render "You are not authorised to access this page."
return false
}
return true
}
def dataLoaderService, idGeneratorService, metadataService

def index = {
redirect(controller: 'manage')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2023 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.collectory

import org.apache.http.HttpStatus


class AdminRoleInterceptor {

CollectoryAuthService collectoryAuthService

AdminRoleInterceptor(){
match(controller: 'admin')
match(controller: 'manage')
match(controller: 'gbif', actionName:'healthCheck')
match(controller: 'gbif', actionName:'healthCheckLinked')
match(controller: 'gbif', actionName:'downloadCSV')
}

boolean before() {
// add an exception for /manage/ and /manage/index/ as it is redirected from /admin/ - which should be visible to all logged in users.
if(controllerName == "manage" && (actionName == "index" || actionName == "list")){
return true
}

// check against configured gbifRegistrationRole for admin gbif methods
if(controllerName == "gbif" && collectoryAuthService?.userInRole(grailsApplication.config.gbifRegistrationRole)){
return true
}

// check roles using userInRoles.userInRole method. also returns true if user has the application configured ROLE_ADMIN.
if (collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN)) {
return true
}
response.sendError(HttpStatus.SC_UNAUTHORIZED)
return false
}



boolean after() { true }

void afterView() {
// no-op
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import java.text.ParseException

class CollectionController extends ProviderGroupController {

def activityLogService, providerGroupService

CollectionController() {
entityName = "Collection"
entityNameLower = "collection"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,25 @@ class CollectoryWebServicesInterceptor {

}
boolean before() {
if (!collectoryAuthService.isAuthorisedWsRequest(params, request, response)) {
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
response.sendError(HttpStatus.SC_UNAUTHORIZED)
// set default role requirement for protected ROLE_EDITOR as the same info is only available to ROLE_EDITOR via the UI.
String[] requiredRoles = [grailsApplication.config.ROLE_EDITOR]

return false
// set gbifRegistrationRole role requirement for GBIF operations
if(controllerName == 'gbif' || actionName == 'syncGBIF'){
requiredRoles = [grailsApplication.config.gbifRegistrationRole]
}
return true

// set ROLE_ADMIN role requirement for certain controllers and actions as per admin UI
if( controllerName == 'ipt'){
requiredRoles = [grailsApplication.config.ROLE_ADMIN]
}

if (collectoryAuthService.isAuthorisedWsRequest(params, request, response, requiredRoles, null)) {
return true
}
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
response.sendError(HttpStatus.SC_UNAUTHORIZED)
return false
}

boolean after() { true }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package au.org.ala.collectory



class ContactController {

static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
Expand All @@ -13,15 +15,6 @@ class ContactController {
def collectoryAuthService
def activityLogService
def providerGroupService

def auth() {
if (!collectoryAuthService?.userInRole(grailsApplication.config.ROLE_EDITOR) && grailsApplication.config.security.oidc.enabled.toBoolean()) {
render "You are not authorised to access this page."
return false
}
return true
}

/**
End access control
*/
Expand Down Expand Up @@ -137,9 +130,9 @@ class ContactController {
* MEW - modified to cascade delete all ContactFor links for the contact
*/
def delete() {
def contactInstance = Contact.get(params.id)
if (contactInstance) {
if (collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN)) {
if (collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN)) {
def contactInstance = Contact.get(params.id)
if (contactInstance) {
try {
activityLogService.log collectoryAuthService?.username(), collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN), Action.DELETE, "contact ${contactInstance.buildName()}"
// need to delete any ContactFor links first
Expand All @@ -158,12 +151,12 @@ class ContactController {
redirect(action: "show", id: params.id)
}
} else {
render "You are not authorised to access this page."
flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'contact.label', default: 'Contact'), params.id])}"
redirect(action: "list")
}
}
else {
flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'contact.label', default: 'Contact'), params.id])}"
redirect(action: "list")
} else{
response.setHeader("Content-type", "text/plain; charset=UTF-8")
render(message(code: "provider.group.controller.04", default: "You are not authorised to access this page."))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,8 @@ class DataController {
def entityInJson
if (clazz == 'DataResource') {
// this auth check (JWT or API key) is a special case handling to support backwards compatibility(which used to check for API key).
def authCheck = collectoryAuthService.isAuthorisedWsRequest(getParams(), request, response)
String [] requiredRoles = [grailsApplication.config.ROLE_ADMIN]
def authCheck = collectoryAuthService.isAuthorisedWsRequest(getParams(), request, response, requiredRoles,null)
entityInJson = crudService."read${clazz}"(params.pg, authCheck)
} else {
entityInJson = crudService."read${clazz}"(params.pg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package au.org.ala.collectory

class DataHubController extends ProviderGroupController {

def activityLogService, providerGroupService

DataHubController() {
entityName = "DataHub"
entityNameLower = "dataHub"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ class DataProviderController extends ProviderGroupController {

def gbifRegistryService
def authService
def activityLogService
def providerGroupService

DataProviderController() {
entityName = "DataProvider"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import au.org.ala.collectory.resources.DarwinCoreFields

class DataResourceController extends ProviderGroupController {

def metadataService, dataImportService, gbifRegistryService, authService, activityLogService, providerGroupService
def metadataService, dataImportService, gbifRegistryService, authService

DataResourceController() {
entityName = "DataResource"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2023 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.collectory

import org.apache.http.HttpStatus


class EditRoleInterceptor {

CollectoryAuthService collectoryAuthService

EditRoleInterceptor(){
match(controller: 'collection')
match(controller: 'institution')
match(controller: 'contact')
match(controller: 'licence', action: 'list')
match(controller: 'licence', action: 'create')
match(controller: 'licence', action: 'edit')
match(controller: 'licence', action: 'show')
match(controller: 'licence', action: 'save')
match('controller':'providerGroup')
match('controller':'providerMap')
match('controller':'providerCode')
match('controller':'dataResource')
match('controller':'dataProvider')
match('controller':'dataHub')
match('controller':'reports')
}

boolean before() {
// check roles using userInRoles.userInRole methods also returns true if user has the application configured ROLE_ADMIN.
if (collectoryAuthService?.userInRole(grailsApplication.config.ROLE_EDITOR)) {
return true
}
response.sendError(HttpStatus.SC_UNAUTHORIZED)
return false
}



boolean after() { true }

void afterView() {
// no-op
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import grails.gorm.transactions.Transactional

class InstitutionController extends ProviderGroupController {

def authService, activityLogService, providerGroupService
def authService

InstitutionController() {
entityName = "Institution"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package au.org.ala.collectory

import au.org.ala.plugins.openapi.Path

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import grails.converters.JSON
import io.swagger.v3.oas.annotations.Operation
Expand All @@ -19,6 +20,7 @@ import javax.ws.rs.Produces
*/
class LicenceController {

def collectoryAuthService
@Operation(
method = "GET",
tags = "licence",
Expand Down Expand Up @@ -143,23 +145,28 @@ class LicenceController {
}

def delete(Long id) {
def licenceInstance = Licence.get(id)
if (!licenceInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'licence.label', default: 'Licence'), id])
redirect(action: "list")
return
}
if (collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN)) {
def licenceInstance = Licence.get(id)
if (!licenceInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'licence.label', default: 'Licence'), id])
redirect(action: "list")
return
}

try {
Licence.withTransaction {
licenceInstance.delete(flush: true)
try {
Licence.withTransaction {
licenceInstance.delete(flush: true)
}
flash.message = message(code: 'default.deleted.message', args: [message(code: 'licence.label', default: 'Licence'), id])
redirect(action: "list")
}
flash.message = message(code: 'default.deleted.message', args: [message(code: 'licence.label', default: 'Licence'), id])
redirect(action: "list")
}
catch (DataIntegrityViolationException e) {
flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'licence.label', default: 'Licence'), id])
redirect(action: "show", id: id)
catch (DataIntegrityViolationException e) {
flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'licence.label', default: 'Licence'), id])
redirect(action: "show", id: id)
}
} else{
response.setHeader("Content-type", "text/plain; charset=UTF-8")
render(message(code: "provider.group.controller.04", default: "You are not authorised to access this page."))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.springframework.dao.DataIntegrityViolationException
class ProviderCodeController {

static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
def collectoryAuthService

def index() {
redirect(action: "list", params: params)
Expand Down Expand Up @@ -87,6 +88,7 @@ class ProviderCodeController {

@Transactional
def delete(Long id) {
if (collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN)) {
def providerCodeInstance = ProviderCode.get(id)
if (!providerCodeInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'providerCode.label', default: 'ProviderCode'), id])
Expand All @@ -103,5 +105,9 @@ class ProviderCodeController {
flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'providerCode.label', default: 'ProviderCode'), id])
redirect(action: "show", id: id)
}
} else{
response.setHeader("Content-type", "text/plain; charset=UTF-8")
render(message(code: "provider.group.controller.04", default: "You are not authorised to access this page."))
}
}
}
Loading

0 comments on commit c2bdc06

Please sign in to comment.