How to only accept post variables in grails - grails

In my controller, I want to accept only POST variables, not the GET Variables. Grails doesn't make any distinction between POST and GET, as far as I know, though the request method can be checked via request.method, but I want to specifically only accept POST parameters. How to go about it? Sorry, if I sound too naive, I have just started groovy and grails with my background in PHP.

Isn't this what the allowedMethods block is for
ie from the documentation:
class PersonController {
// action1 may be invoked via a POST
// action2 has no restrictions
// action3 may be invoked via a POST or DELETE
static allowedMethods = [action1:'POST',
action3:['POST', 'DELETE']]
def action1 = { … }
def action2 = { … }
def action3 = { … }
}

Related

Access controller request params in BootStrap.groovy

I am new to grails and I am trying to override the redirect method in groovy controller. I refereed this Override Grails redirect method. But I do not understand how do I access and pass the http request params to the redirect override in BootStrap.groovy.
redirect(action: "logout", params: [lang: params.lang])
If you implement a wrapper via metaClass on a controller (just like mentioned in your linked question), you can simply access the "active" controller object via "delegate" in your implementation closure:
def ctx = servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
def app = ctx.getBean("grailsApplication")
app.controllerClasses.each() { controllerClass ->
def oldRedirect = controllerClass.metaClass.pickMethod("redirect", [Map] as Class[])
controllerClass.metaClass.redirect = { Map args ->
// delegate is the instance of <controllerClass> where "redirect" just gets executed.
// the current http request can be accessed via a getter on controller classes
println delegate.getRequest()
oldRedirect.invoke delegate, args
}
}
alternatively, you could use the RequestContextHolder to obtain the current requestAttributes and extract the request from there (see org.codehaus.groovy.grails.plugins.web.api.CommonWebApi.java in Grails 2 or grails.web.api.ServletAttributes.groovy in Grails 3)

How do I get controller method params when using #Secured closure?

I have successfully set up my Grails application to authenticate the user.
I map controller method arguments using URL params, in my UrlMappings.groovy:
"/$source/owner/$ownerId/show"(controller:"myController", action: "show", method: "GET")
How do I get the values of $source and $ownerId in my #Secured closure?
My controller method looks like this:
#Secured(closure = {
//null
def testSource = params.source
//also null
def testOwnerId = params.ownerId
//null
def owner = request.ownerId
//null
def owner2 = request.getParameter('ownerId')
//contains only query string params
def grailsParams = request['org.codehaus.groovy.grails.WEB_REQUEST']?.params
return true
})
def show(String source, String ownerId) {
...
}
How do I get these values? What am I doing wrong, here?
I thought that this post would provide a solution, but the answer given there didn't work for me:
Is it possible to hack the spring-security-core plugin #Secured annotation to be able to reference request params given to a controller?
I am using the following grails and plugin versions:
grails 2.5.1
compile ":spring-security-core:2.0-RC5"
compile ":spring-security-rest:1.5.3", {
excludes 'com.fasterxml.jackson.core:jackson-databind:'
}
Brief :
Use request.getParameter
Details :
In 2.0 you can use a closure as the annotation's check; there's a brief writeup and example in the docs: https://grails-plugins.github.io/grails-spring-security-core/v2/guide/newInV2.html
You'd express your example as this:
#Secured(closure={
request.getParameter('ownerId') >=123 //this is example
})
Return true to allow access, false to deny access.

Spock No thread-bound request found

I have created a simple util class UtilService.groovy and when I tried to run write test case for it.
class UtilService {
static transactional = true
def messageSource
HttpServletRequest getCurrentRequest() {
GrailsWebRequest webUtils = WebUtils.retrieveGrailsWebRequest()
def request = webUtils.getCurrentRequest()
return request
}
String getMessage(String code, Object[] args = null, String defaultMessage = null) {
HttpServletRequest request = currentRequest
Locale locale = request.locale
if (defaultMessage) {
return messageSource.getMessage(code, args, defaultMessage, locale)
} else {
return messageSource.getMessage(code, args, locale)
}
}
Test case
#TestMixin(GrailsUnitTestMixin)
class UtilServiceSpec extends Specification {
void "Test get message"() {
setup:
def utilService = new UtilService()
when:
String data = utilService.getMessage("payCode.label")
then:
data == "Pay Code"
}
}
Error:
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread?
I have searched and try some links from google but they did not work for me.
Obviously, you are doing it outside of web request, WebUtils.retrieveGrailsWebRequest() will fail because there's no web request going on. If your service is called from a controller during tests it should work.
Instead of you service depending on WebRequest, why don't you pass the Locale as an argument to getMessage, controllers can call getMessage and pass the request Locale, or else the service will choose the default locale. Its generally not good idea to have services be aware of web apis (eg requests, response, session etc). And you will be able to test both service and controller.
I have written Integration test for this requirement rather than Unit test and able to run my test cases successfully.

Grails: On 404 error need to know name of controller and action that caused it

In the URL mapping file, i have connected 404 error with ErrorController's notFound action.
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"500"(controller: "errorPage", action: "internalError")
"403"(controller: "errorPage", action: "forbidden")
"404"(controller: "errorPage", action: "notFound")
}
If any controller does not makes render call and a default view does not exists for that action, it invokes the notFound action of ErrorPageController. Now, I want to know in this notFound action which action was called due to which the 404 exception was invoked. How can that be known? For example, in case of 500, the internalError action get request.exception through which we know what happened that invoked internalError. Same needs to be done for 404 error.
I've tried this controller:
package test
class ErrorPageController {
def grailsUrlMappingsHolder
def grailsApplication
def notFound() {
// retrieve uri without context (if any)
def uri = request.forwardURI - "/${grailsApplication.metadata['app.name']}"
// try to parse uri agains defined urlMappings to get parameters
def parameters = grailsUrlMappingsHolder.match(uri)?.parameters ?: [:]
[previousAction : parameters.action, previousController: parameters.controller]
}
}
I have assumed that in your path the context is your appName, you may have to adjust it accordingly.
You could probably use grails wildcard filters like mentioned http://grails.org/doc/2.2.1/ref/Plug-ins/filters.html
Then print the things you need like controllername and action here. The filter get called before every controller / action execution.

Detect redirect in Grails

At the end of my save action I redirect to the show action like this:
redirect(action: "show", id: exampleInstance.id)
In my show action I want to be able to detect if someone came directly to this action via a url, or if they were redirected here from another action. I tried request.isRedirected() but it always returns false.
How do I detect if I am in an action as the result of a redirect from another action?
I guess you want to display a confirmation message. Grails has a built-in feature for this kind of use-case:
http://www.grails.org/doc/2.1.0/ref/Controllers/flash.html
Have a look at the example:
class BookController {
def save() {
flash.message = "Welcome!"
redirect(action: 'home')
}
}
In the view you can print or check against flash.message.
In theory, isRedirect checks request attributes. It is equivalent to
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes
if(request.getAttribute(GrailsApplicationAttributes.REDIRECT_ISSUED) != null){
println "request was redirect"
}
Try it directly and tell me what happens.
It looks like in the Grails source that isRedirected() is only applicable to the save action, as it gets set in the redirect() method logic, and so wouldn't be set in the show action.
Instead, here are some manual options. One is to add a flag to the flash object, which is then tested in the redirect action. Since it is in flash scope it will be cleared at the end of the show action:
def save() {
// Do stuff
flash.redirectFrom = "save"
redirect(action:"show")
}
def show() {
if (flash.redirectFrom) {
// Respond to redirect
}
// Do other stuff
}
Another option is to issue a chain() call instead of a redirect() and test for the implicit chainModel object. The chainModel won't exist when the show action is requested from an external URL:
def save() {
// Do stuff
chain(action:"show",model:[from:'show'])
}
def show() {
if (chainModel) {
// Respond to redirect
}
// Do other stuff
}

Resources