Skip to content

Commit

Permalink
Merge pull request #3045 from AtlasOfLivingAustralia/hotfix/3.0.2
Browse files Browse the repository at this point in the history
Hotfix/3.0.2
  • Loading branch information
chrisala authored Nov 29, 2023
2 parents 9ea788d + 192922b commit 8def817
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 26 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
meritVersion=3.0.1
meritVersion=3.0.2-SNAPSHOT
grailsVersion=5.3.2
grailsGradlePluginVersion=5.3.0
groovyVersion=3.0.11
Expand All @@ -16,4 +16,4 @@ org.gradle.jvmargs=-Xmx2048M
seleniumVersion=3.12.0
seleniumSafariDriverVersion=3.14.0
snapshotCacheTime=1800
alaSecurityLibsVersion=6.0.4
alaSecurityLibsVersion=6.2.0
5 changes: 3 additions & 2 deletions grails-app/conf/application.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ grails {
ehcache.directory = '/data/fieldcapture/ehcache'

auth.baseUrl = 'https://auth-test.ala.org.au'
userDetails.url = "${auth.baseUrl}/userdetails/"
userDetails.web.url = "${auth.baseUrl}/userdetails/"
userDetails.api.url = "${auth.baseUrl}/userdetails/userDetails/"
user.registration.url = "${auth.baseUrl}/userdetails/registration/createAccount"
security {
cas {
Expand Down Expand Up @@ -296,7 +297,7 @@ environments {
security.cas.loginUrl="${security.cas.casServerUrlPrefix}/login"
security.cas.casLoginUrl="${security.cas.casServerUrlPrefix}/login"
security.cas.logoutUrl="${security.cas.casServerUrlPrefix}/logout"
userDetails.url = "${casBaseUrl}/userdetails/userDetails/"
userDetails.api.url = "${casBaseUrl}/userdetails/userDetails/"
logging.dir = '.'
upload.images.path = '/tmp'
upload.images.url = grails.serverURL+'/image/'
Expand Down
5 changes: 4 additions & 1 deletion grails-app/services/au/org/ala/merit/SiteService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,10 @@ class SiteService {

private Map createSite(String projectId, String name, String description, String externalId, String source, Map geometry, String geometryPid = null) {

Map values = [type:'worksArea', extent: [source: source, geometry: geometry], projects: [projectId], name: name, description: description, externalId:externalId, visibility:'private']
// Spatial portal is now returning a geojson of type 'Feature' instead of a geometry object
// support both
Map siteGeometry = geometry.geometry ? geometry.geometry : geometry
Map values = [type:'worksArea', extent: [source: source, geometry: siteGeometry], projects: [projectId], name: name, description: description, externalId:externalId, visibility:'private']
if (geometryPid && !"null".equals(geometryPid)) {
values.extent.geometry.pid = geometryPid
values.extent.pid = geometryPid
Expand Down
11 changes: 5 additions & 6 deletions grails-app/services/au/org/ala/merit/SpatialService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class SpatialService {
Integer deleteFromSpatialPortal(String pid) {
String url = "${grailsApplication.config.getProperty('spatial.layersUrl')}${DELETE_SHAPE_PATH}/$pid"

webService.doDelete(url)
webService.doDelete(url, true)
}

/**
Expand All @@ -41,10 +41,9 @@ class SpatialService {
* attributes of that feature. eg. [shp_id: <shapefileId>, "0":[attribute1:<value>, attribute2:<value>, etc], "1":[attribute1:<value>, attribute2:<value>, etc]]]
*/
Map uploadShapefile(MultipartFile shapefile) {
String userId = userService.getCurrentUserId()
String url = "${grailsApplication.config.getProperty('spatial.layersUrl')}${UPLOAD_SHAPE_PATH}?user_id=${userId}&api_key=${grailsApplication.config.getProperty('api_key')}"
String url = "${grailsApplication.config.getProperty('spatial.layersUrl')}${UPLOAD_SHAPE_PATH}"

webService.postMultipart(url, [:], shapefile)
webService.postMultipart(url, [:], shapefile, 'files', true)
}

/**
Expand All @@ -62,11 +61,11 @@ class SpatialService {
String baseUrl = "${grailsApplication.config.getProperty('spatial.layersUrl')}${UPLOAD_SHAPE_PATH}"
String userId = userService.getCurrentUserId()

Map site = [name:objectName, description: objectDescription, user_id:userId, api_key:grailsApplication.config.getProperty('api_key')]
Map site = [name:objectName, description: objectDescription, user_id:userId]

String url = "${baseUrl}/${shapeFileId}/${featureId}"

webService.doPost(url, site)
webService.doPost(url, site, true)
}

/**
Expand Down
59 changes: 47 additions & 12 deletions grails-app/services/au/org/ala/merit/WebService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package au.org.ala.merit

import au.org.ala.ws.tokens.TokenService
import grails.converters.JSON
import grails.core.GrailsApplication
import grails.web.http.HttpHeaders
Expand All @@ -40,6 +41,8 @@ import javax.servlet.http.HttpServletResponse
@Slf4j
class WebService {

TokenService tokenService

// Used to avoid a circular dependency during initialisation
def getUserService() {
return grailsApplication.mainContext.userService
Expand Down Expand Up @@ -99,16 +102,27 @@ class WebService {
grailsApplication.config.getProperty('webservice.connectTimeout', Integer, 2000)
}

private URLConnection configureConnection(String url, boolean includeUserId, Integer timeout = null) {
private URLConnection configureConnection(String url, boolean includeUserId, Integer timeout = null, boolean useToken = false) {
URLConnection conn = createAndConfigureConnection(url, timeout)
conn.setRequestProperty("Authorization", grailsApplication.config.getProperty('api_key'));
if (!useToken) {
conn.setRequestProperty("Authorization", grailsApplication.config.getProperty('api_key'))
}
else {
conn.setRequestProperty("Authorization", getToken())
}


def user = getUserService().getUser()
if (user) {
conn.setRequestProperty(grailsApplication.config.getProperty('app.http.header.userId'), user.userId)
}
conn
}

private String getToken() {
tokenService.getAuthToken(false)?.toAuthorizationHeader()
}

private URLConnection createAndConfigureConnection(String url, Integer timeout = null) {
URLConnection conn = new URL(url).openConnection()

Expand Down Expand Up @@ -352,20 +366,26 @@ class WebService {
}
}

def doPost(String url, Map postBody) {
def doPost(String url, Map postBody, boolean useToken = false) {
def conn = null
def charEncoding = 'utf-8'
try {
conn = new URL(url).openConnection()
conn.setDoOutput(true)
conn.setRequestProperty("Content-Type", "application/json;charset=${charEncoding}");
conn.setRequestProperty("Authorization", grailsApplication.config.getProperty('api_key'));

if (useToken) {
conn.setRequestProperty("Authorization", getToken())
}
else {
conn.setRequestProperty("Authorization", grailsApplication.config.getProperty('api_key'));
}
def user = getUserService().getUser()
if (user) {
conn.setRequestProperty(grailsApplication.config.getProperty('app.http.header.userId'), user.userId) // used by ecodata
conn.setRequestProperty("Cookie", "ALA-Auth="+java.net.URLEncoder.encode(user.userName, charEncoding)) // used by specieslist
}


OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream(), charEncoding)
wr.write((postBody as JSON).toString())
wr.flush()
Expand All @@ -389,17 +409,26 @@ class WebService {
}
}

def doDelete(String url) {
url += (url.indexOf('?') == -1 ? '?' : '&') + "api_key=${grailsApplication.config.getProperty('api_key')}"
def doDelete(String url, boolean useToken = false) {
if (!useToken) {
url += (url.indexOf('?') == -1 ? '?' : '&') + "api_key=${grailsApplication.config.getProperty('api_key')}"
}

def conn = null
try {
conn = new URL(url).openConnection()
conn.setRequestMethod("DELETE")
conn.setRequestProperty("Authorization", grailsApplication.config.getProperty('api_key'));
if (useToken) {
conn.setRequestProperty("Authorization", getToken())
}
else {
conn.setRequestProperty("Authorization", grailsApplication.config.getProperty('api_key'))
}
def user = getUserService().getUser()
if (user) {
conn.setRequestProperty(grailsApplication.config.getProperty('app.http.header.userId'), user.userId)
}

return conn.getResponseCode()
} catch(Exception e){
println e.message
Expand All @@ -418,9 +447,9 @@ class WebService {
* @param file the Multipart file object to forward.
* @return [status:<request status>, content:<The response content from the server, assumed to be JSON>
*/
def postMultipart(url, Map params, MultipartFile file, fileParam = 'files') {
def postMultipart(url, Map params, MultipartFile file, fileParam = 'files', boolean useToken = false) {

postMultipart(url, params, file.inputStream, file.contentType, file.originalFilename, fileParam)
postMultipart(url, params, file.inputStream, file.contentType, file.originalFilename, fileParam, null, useToken)
}

/**
Expand All @@ -434,7 +463,7 @@ class WebService {
* @param successHandler optional callback for a successful service invocation. If not supplied, a Map will be returned.
* @return [status:<request status>, content:<The response content from the server, assumed to be JSON>
*/
def postMultipart(url, Map params, InputStream contentIn, contentType, originalFilename, fileParamName = 'files', Closure successHandler = null) {
def postMultipart(url, Map params, InputStream contentIn, contentType, originalFilename, fileParamName = 'files', Closure successHandler = null, boolean useToken = false) {

def result = [:]
def user = userService.getUser()
Expand All @@ -449,13 +478,19 @@ class WebService {
content.addPart(key, new StringBody(value.toString()))
}
}
headers.'Authorization' = grailsApplication.config.getProperty('api_key')
if (useToken) {
headers.'Authorization' = getToken()
}
else {
headers.'Authorization' = grailsApplication.config.getProperty('api_key')
}
if (user) {
headers[grailsApplication.config.getProperty('app.http.header.userId')] = user.userId
}
else {
log.warn("No user associated with request: ${url}")
}

request.setEntity(content)

if (successHandler) {
Expand Down
6 changes: 3 additions & 3 deletions src/test/groovy/au/org/ala/merit/SpatialServiceSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SpatialServiceSpec extends Specification implements AutowiredTest{
Integer status = service.deleteFromSpatialPortal(pid)

then:
1 * webService.doDelete("/shape/upload/$pid") >> HttpStatus.SC_OK
1 * webService.doDelete("/shape/upload/$pid", true) >> HttpStatus.SC_OK
status == HttpStatus.SC_OK
}

Expand All @@ -53,7 +53,7 @@ class SpatialServiceSpec extends Specification implements AutowiredTest{
Map result = service.uploadShapefile(file)

then:
1 * webService.postMultipart("/shape/upload/shp?user_id=$userId&api_key=${config.api_key}", [:], file) >> [statusCode:HttpStatus.SC_OK, resp:resp]
1 * webService.postMultipart("/shape/upload/shp", [:], file, 'files', true) >> [statusCode:HttpStatus.SC_OK, resp:resp]
result.statusCode == HttpStatus.SC_OK
result.resp == resp

Expand All @@ -73,7 +73,7 @@ class SpatialServiceSpec extends Specification implements AutowiredTest{
Map result = service.createObjectFromShapefileFeature(shapefileId, featureId, name, description)

then:
1 * webService.doPost("/shape/upload/shp/$shapefileId/$featureId", [user_id:userId, api_key:config.api_key, name:name, description:description]) >> [statusCode:HttpStatus.SC_OK, resp:resp]
1 * webService.doPost("/shape/upload/shp/$shapefileId/$featureId", [user_id:userId, name:name, description:description], true) >> [statusCode:HttpStatus.SC_OK, resp:resp]
result.statusCode == HttpStatus.SC_OK
result.resp == resp

Expand Down

0 comments on commit 8def817

Please sign in to comment.