From ec01768ab2d83fd1e016bae5b965e3ebc9bb382d Mon Sep 17 00:00:00 2001 From: Sushant G <105408469+sughics@users.noreply.github.com> Date: Thu, 15 Dec 2022 11:53:31 +1100 Subject: [PATCH 01/10] Bumping SNAPSHOT version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9feaddce..3e3d0e7c 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ plugins { id "com.gorylenko.gradle-git-properties" version "2.4.0-rc2" } -version "3.1.1-SNAPSHOT" +version "3.1.2-SNAPSHOT" group "au.org.ala" From a19f9df39feb22bff6e0fb40e16b6648da60d32e Mon Sep 17 00:00:00 2001 From: Sushant <105408469+sughics@users.noreply.github.com> Date: Fri, 13 Jan 2023 17:20:02 +1100 Subject: [PATCH 02/10] issue #175 adding AlaSecured annotation to relevant controllers and methods, updating legacy use of ROLE_COLLECTION_ADMIN and ROLE_COLLECTION_EDITOR --- grails-app/conf/application.yml | 1 + .../org/ala/collectory/AdminController.groovy | 11 ++---- .../ala/collectory/ContactController.groovy | 16 +++------ .../ala/collectory/LicenceController.groovy | 36 +++++++++++-------- .../collectory/ProviderGroupController.groovy | 19 +++++----- .../collectory/ProviderMapController.groovy | 21 +++++------ .../ala/collectory/CollectoryTagLib.groovy | 8 ++--- grails-app/views/manage/list.gsp | 24 ++++++------- 8 files changed, 63 insertions(+), 73 deletions(-) diff --git a/grails-app/conf/application.yml b/grails-app/conf/application.yml index 15ee4de1..cfaadf17 100644 --- a/grails-app/conf/application.yml +++ b/grails-app/conf/application.yml @@ -209,6 +209,7 @@ biocacheUiURL: https://biocache.ala.org.au isPipelinesCompatible: true ROLE_ADMIN: 'ROLE_ADMIN' +ROLE_EDITOR: 'ROLE_EDITOR' rifcs: excludeBounds: true diff --git a/grails-app/controllers/au/org/ala/collectory/AdminController.groovy b/grails-app/controllers/au/org/ala/collectory/AdminController.groovy index cdd68480..49fa1c46 100644 --- a/grails-app/controllers/au/org/ala/collectory/AdminController.groovy +++ b/grails-app/controllers/au/org/ala/collectory/AdminController.groovy @@ -1,21 +1,16 @@ package au.org.ala.collectory +import au.org.ala.web.AlaSecured import com.opencsv.CSVReader import grails.converters.JSON import grails.web.JSONBuilder import org.springframework.core.io.support.PathMatchingResourcePatternResolver + +@AlaSecured(value = ["ROLE_ADMIN"], message = "You are not authorised to access this page. You do not have 'Admin' rights.") class AdminController { def dataLoaderService, idGeneratorService, collectoryAuthService, metadataService, activityLogService, providerGroupService - 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 index = { redirect(controller: 'manage') } diff --git a/grails-app/controllers/au/org/ala/collectory/ContactController.groovy b/grails-app/controllers/au/org/ala/collectory/ContactController.groovy index eaea0145..37266c1d 100644 --- a/grails-app/controllers/au/org/ala/collectory/ContactController.groovy +++ b/grails-app/controllers/au/org/ala/collectory/ContactController.groovy @@ -1,5 +1,8 @@ package au.org.ala.collectory +import au.org.ala.web.AlaSecured + +@AlaSecured(value = ["ROLE_ADMIN", "ROLE_EDITOR"], anyRole = true, message = "You are not authorised to access this page. You do not have 'editor' rights.") class ContactController { static allowedMethods = [save: "POST", update: "POST", delete: "POST"] @@ -14,14 +17,6 @@ class ContactController { 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 */ @@ -136,10 +131,10 @@ class ContactController { /** * MEW - modified to cascade delete all ContactFor links for the contact */ + @AlaSecured(value = ["ROLE_ADMIN"], message = "You are not authorised to access this page.") def delete() { def contactInstance = Contact.get(params.id) if (contactInstance) { - if (collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN)) { try { activityLogService.log collectoryAuthService?.username(), collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN), Action.DELETE, "contact ${contactInstance.buildName()}" // need to delete any ContactFor links first @@ -157,9 +152,6 @@ class ContactController { flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'contact.label', default: 'Contact'), params.id])}" redirect(action: "show", id: params.id) } - } else { - render "You are not authorised to access this page." - } } else { flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'contact.label', default: 'Contact'), params.id])}" diff --git a/grails-app/controllers/au/org/ala/collectory/LicenceController.groovy b/grails-app/controllers/au/org/ala/collectory/LicenceController.groovy index 7c16c9b5..741bc89e 100644 --- a/grails-app/controllers/au/org/ala/collectory/LicenceController.groovy +++ b/grails-app/controllers/au/org/ala/collectory/LicenceController.groovy @@ -1,6 +1,7 @@ package au.org.ala.collectory import au.org.ala.plugins.openapi.Path +import au.org.ala.web.AlaSecured import com.fasterxml.jackson.annotation.JsonIgnoreProperties import grails.converters.JSON import io.swagger.v3.oas.annotations.Operation @@ -17,8 +18,11 @@ import javax.ws.rs.Produces /** * Simple webservice providing support licences in the system. */ +@AlaSecured(value = ["ROLE_ADMIN", "ROLE_EDITOR"], anyRole = true, message = "You are not authorised to access this page. You do not have 'Collection editor' rights.") class LicenceController { + def collectoryAuthService + @Operation( method = "GET", tags = "licence", @@ -143,23 +147,25 @@ 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") + } + catch (DataIntegrityViolationException e) { + flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'licence.label', default: 'Licence'), id]) + redirect(action: "show", id: id) } - 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) } } } diff --git a/grails-app/controllers/au/org/ala/collectory/ProviderGroupController.groovy b/grails-app/controllers/au/org/ala/collectory/ProviderGroupController.groovy index cde9ea76..685d1ee9 100644 --- a/grails-app/controllers/au/org/ala/collectory/ProviderGroupController.groovy +++ b/grails-app/controllers/au/org/ala/collectory/ProviderGroupController.groovy @@ -1,5 +1,6 @@ package au.org.ala.collectory +import au.org.ala.web.AlaSecured import grails.converters.JSON import org.springframework.dao.DataIntegrityViolationException import org.springframework.web.context.request.RequestContextHolder @@ -10,6 +11,7 @@ import org.springframework.web.multipart.MultipartFile * * It provides common code for shared attributes like contacts. */ +@AlaSecured(value = ["ROLE_ADMIN", "ROLE_EDITOR"], anyRole = true, message = "You are not authorised to access this page. You do not have 'editor' rights.") abstract class ProviderGroupController { String entityName = "ProviderGroup" @@ -18,20 +20,19 @@ abstract class ProviderGroupController { def idGeneratorService, collectoryAuthService, metadataService, gbifService, dataImportService, providerGroupService, activityLogService - def auth() { - if (!collectoryAuthService?.userInRole(grailsApplication.config.ROLE_EDITOR) && grailsApplication.config.security.oidc.enabled.toBoolean()) { - response.setHeader("Content-type", "text/plain; charset=UTF-8") - render message(code: "provider.group.controller.01", default: "You are not authorised to access this page. You do not have 'Collection editor' rights.") - return false - } - } + /* + * Access control + * + * All methods require EDITOR role. + * Edit methods require ADMIN or the user to be an administrator for the entity. + */ // helpers for subclasses protected username = { collectoryAuthService?.username() ?: 'unavailable' } - protected isAdmin = { + protected isAdmin () { collectoryAuthService?.userInRole(grailsApplication.config.ROLE_ADMIN) ?: false } /* @@ -853,7 +854,7 @@ abstract class ProviderGroupController { } protected boolean isAuthorisedToEdit(uid) { - if (!grailsApplication.config.security.oidc.enabled.toBoolean() || isAdmin()) { + if (isAdmin()) { return true } else { def email = RequestContextHolder.currentRequestAttributes()?.getUserPrincipal()?.name diff --git a/grails-app/controllers/au/org/ala/collectory/ProviderMapController.groovy b/grails-app/controllers/au/org/ala/collectory/ProviderMapController.groovy index 46d82660..6e63d4ff 100644 --- a/grails-app/controllers/au/org/ala/collectory/ProviderMapController.groovy +++ b/grails-app/controllers/au/org/ala/collectory/ProviderMapController.groovy @@ -1,26 +1,21 @@ package au.org.ala.collectory +import au.org.ala.web.AlaSecured import grails.gorm.transactions.Transactional +@AlaSecured(value =["ROLE_ADMIN", "ROLE_EDITOR"], anyRole = true, message = "You are not authorised to access this page. You do not have 'editor' rights.") class ProviderMapController { static allowedMethods = [save: "POST", update: "POST", delete: "POST"] def collectoryAuthService -/* - * Access control - * - * All methods require EDITOR role. - * Edit methods require ADMIN or the user to be an administrator for the entity. - */ - def beforeInterceptor = [action:this.&auth] - 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 - } - } + /* + * Access control + * + * All methods require EDITOR role. + * Edit methods require ADMIN or the user to be an administrator for the entity. + */ def index = { redirect(action: "list", params: params) diff --git a/grails-app/taglib/au/org/ala/collectory/CollectoryTagLib.groovy b/grails-app/taglib/au/org/ala/collectory/CollectoryTagLib.groovy index c09ed8b8..58103bfd 100644 --- a/grails-app/taglib/au/org/ala/collectory/CollectoryTagLib.groovy +++ b/grails-app/taglib/au/org/ala/collectory/CollectoryTagLib.groovy @@ -80,7 +80,7 @@ class CollectoryTagLib { } /** - * + * * All the listed roles must be granted for the tag to output its body. * */ @@ -102,7 +102,7 @@ class CollectoryTagLib { } /** - * + * * The specified role must be granted for the tag to output its body. * * @attr role the role to check @@ -114,7 +114,7 @@ class CollectoryTagLib { } /** - * + * * The specified role must be missing for the tag to output its body. * * @attr role the role to check @@ -130,7 +130,7 @@ class CollectoryTagLib { */ def roles = { def roles = [] - ['ROLE_ADMIN','ROLE_COLLECTION_EDITOR','ROLE_COLLECTION_ADMIN'].each { + ['ROLE_ADMIN','ROLE_EDITOR'].each { if (collectoryAuthService.userInRole(it)) { roles << it } diff --git a/grails-app/views/manage/list.gsp b/grails-app/views/manage/list.gsp index 3dbfb3f6..b6e84399 100644 --- a/grails-app/views/manage/list.gsp +++ b/grails-app/views/manage/list.gsp @@ -41,8 +41,8 @@

${username}.

-

User ${request.isUserInRole('ROLE_COLLECTION_ADMIN') ? 'has' : 'does not have'} ROLE_COLLECTION_ADMIN.

-

User ${request.isUserInRole('ROLE_COLLECTION_EDITOR') ? 'has' : 'does not have'} ROLE_COLLECTION_EDITOR.

+

User ${request.isUserInRole('ROLE_ADMIN') ? 'has' : 'does not have'} ROLE_ADMIN.

+

User ${request.isUserInRole('ROLE_EDITOR') ? 'has' : 'does not have'} ROLE_EDITOR.

.

@@ -76,17 +76,17 @@ - +

.

- +

.

- +

.

- +

.

@@ -109,16 +109,16 @@

.

- +

- +

!

- ROLE_COLLECTION_EDITOR.

+ ROLE_EDITOR.

- +

!

@@ -126,7 +126,7 @@

.

- +

.

.

@@ -143,7 +143,7 @@