Sending Stripe Webhooks to Controller in Grails - grails

I am trying to capture a test web hook from Stripe on Grails(2.5.1). I setup a line in my URLmappings which when going directly to the URL on a browser on my local machine running ngrok executes the controller method ok. I cannot seem to get the Stripe payload to the controller however? Thanks!
//UrlMappings.groovy
class UrlMappings {
static mappings = {
"/stripe-demo" (controller: 'charge', action: 'respond')
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
}
//Controller
package stripe.demo
class ChargeController {
def respond(String payload){
//capture the payload sent by Stripe and do something, also respond with 200.
}
}

The stripe webhook data comes in request.JSON so databinding it to a String like that won't work. Here's an example:
class ChargeController {
def webHook() {
if(request.JSON) {
// do something with it, eg:
switch(request.JSON.type) { }
}
render '' // sends nothing back but a http 200
}
}
And then set the webhook to https://example.com/charge/webHook (note, it must be accessable to stripe so localhost wont work)

Related

Grails 3 interceptors and controller by example

I am experimenting with Grails 3 and its new concept of interceptors. Given the following interceptor/controller:
class AuthInterceptor {
// ...other stuff in here
boolean before() {
if(FizzBuzz.isFoo()) {
redirect(controller: auth, action: signin)
true
} else {
true
}
}
}
class AuthController {
AuthService authService
def signin() {
String username = params[username]
String password = params[password]
user = authService.authenticate(username, password)
if(user) {
SimpleSecurityUtils.setCurrentUser(user)
redirect(url: ??? INTENDED_DESTINATION ???)
} else {
// Auth failed.
redirect(action: failed)
}
}
}
AuthService is a Grails Service. I would like there to be one instance of AuthService per instance of AuthController. And I would like AuthController to have prototype scope such that I am never storing state, and a controller is created for each request. What do I have to change in both (AuthService/AuthController) to meet these scope requirements?
Assuming AuthController#signin is executed due to a redirect(controller:auth, action: signin) inside an interceptor, how do I redirect (yet again) the user to their intended destination (that is, the URL they wanted to go to prior to the interceptor intercepting the request) from inside the controller action above?
First, if you redirect to another URL, you must return false to cancel the rendering process, e.g.
redirect(controller: auth, action: signin)
false
Second, if you want back to previews intended URL, you must save it, may be, to session, and then you redirect to the saved URL when you finish signin process.

Accessing specific controller in grails shiro plugin

I have a grails application in which I am using shiro plugin to add security. I do not give access to any of the urls without login to any user. All goes fine. Now I want to find whether there is any way to allow access to some of the urls without login ? Some links should be working without login.
that's easy. If you've a standard shiro setup, you'll find a ShiroSecurityFilters.groovy in your projects conf-folder which looks something like this:
class SecurityFilters {
def filters = {
all(uri: "/**") {
before = {
// Ignore direct views (e.g. the default main index page).
if (!controllerName) return true
// Access control by convention.
accessControl()
}
}
}
}
just replace it with something like this:
class SecurityFilters {
def filters = {
all(uri: "/**") {
before = {
// Ignore direct views (e.g. the default main index page).
if (!controllerName) return true
// Access control by convention.
if ((controllerName+':'+actionName) in ['book:view', 'book:list']) {
return true
} else {
accessControl()
}
}
}
}
}
This will make the two actions list and view of the bookController accessible to everyone.
Hope that helps...

Setting up the filter without controllers

I have a running tomcat at localost.
I wish to write a grails filter such that when ever user goes to localhost/filter/ intercept the call and do some processing. I created a filter which is inside conf folder
class TestFilters {
def filters = {
filter(uri:'/filter') {
before = {
}
after = {
}
afterView = {
}
}
}
}
after setting this up when I go to localhost/filter/ I get only 404 error.
Where I'm making the mistake?
Thanks in advance
If you have no FilterController the url localhost/filter has no ressource to show - so you get a 404 error. You have to adapt your UrlMappings so that localhost/filter is a valid url of application.
Add the following to UrlMappings.groovy:
"/filter" (controller: "yourController", action:"yourAction")
Now - the url localhost/filter points to yourAction in yourController and the filter should be applied.

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
}

Grails 1.3.7 picks wrong view for controller

I have controller named LoginController with action auth:
class LoginController {
def auth = {
render view: 'auth'
}
}
So I go to the URL http://localhost:8080/myapp/login/auth, and want to see my view '/login/auth.gsp'. But I get the following error:
type Status report
message /myapp/WEB-INF/grails-app/views/jobSearch/auth.jsp
description The requested resource (/myapp/WEB-INF/grails-app/views/jobSearch/auth.jsp) is not available.
Seems that grails resolves wrong view name for some reason. Do you know, what's going on?
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints { // apply constraints here }
}
"/"(view:"/index") "500"(view:'/error')
}
}
Agree with #omarello, something looks like its mapping the login controller URL to 'jobsearch'. The error message relating to JSP is what happens when it can't find a matching gsp page and tries to fallback to JSP.

Resources