Setting up the filter without controllers - grails

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.

Related

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...

Does Grails Filter `actionExclude` work with method-based routing?

I have a method-based route like:
name base: "/" {
controller="api"
action=[GET: "welcome", POST: "post"]
}
And I'd like to apply a filter to handle authorization, e.g.
class RequestFilters {
def filters = {
authorizeRequest(controller: 'api', actionExclude: 'welcome') {
before = {
log.debug("Applying authorization filter.")
}
}
}
}
But when I apply this in practice, the filter runs on all requests (even GET requests, which should use the welcome method and thus should not trigger this filter.)
When I inspect the code running the in the filter, I see that params.action is set to the Map from my routing file, rather than to "welcome". Not sure if this is related to the issue.
My current workaround (which feels very wrong) is to add the following to my filter's body:
if(params.action[request.method] == 'welcome'){
return true
}
The short question is: does Grails support this combination of method-based routing + action-name-based filtering? If so, how? If not, what are some reasonable alternatives for restructuring this logic?
Thanks!
You need to use the filter as below:
class RequestFilters {
def filters = {
authorizeRequest(controller:'api', action:'*', actionExclude:'welcome'){
before = {
log.debug("Applying authorization filter.")
return true
}
}
}
}
Apply the filter to all actions of the controller but "welcome". :)
If there is no other welcome action in the other controllers then, you would not need the controller specified in the filter as well.
authorizeRequest(action:'*', actionExclude:'welcome'){...}

Grails UrlMapping route to fixed controller and action

I made the following rule in my UrlMapping file and now all my controllers are matching to the ("/$username") mapping, not the first one ("/$controller/$action?/$id?").
The idea here was to list all public items from an user using a short url. It works but it breaks all others controllers.
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/$username" {
controller = 'user'
action = 'publicItens'
}
"/"(controller:'usuario', action: 'index' )
"500"(view:'/error')
}
How can I map it correctly?
solved!
I just wrote some code in the UrlMappings to create rules automatically for each controller in the application. Using this approach when the user types /appname/controllerName then the rule created automatically is considered in place of the "$/username" rule.
The critical point is that the use of ApplicationHolder which is deprecated. That can fixed writing your own ApplicationHolder.
static mappings = {
//creates one mapping rule for each controller in the application
ApplicationHolder.application.controllerClasses*.logicalPropertyName.each { cName ->
"/$cName" {
controller = cName
}
}
"/$controller/$action?/$id?"{
}
"/$username" {
controller = 'usuario'
action = 'itensPublicos'
}
"/"(controller:'usuario', action: 'index' )
"500"(view:'/error')
}
Just add /users/$username to the URL mapping. This is the simplest way how to achieve your goals.
"/users/$username" {
controller = 'user'
action = 'publicItens'
}
You could probably also exclude the user and usario controllers in the first url mapping constraints(notEqual)
http://www.grails.org/doc/latest/ref/Constraints/notEqual.html

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.

Can I have a circular redirect in Grails?

I'm trying to redirect circularly in Grails (no infinite redirect loop) and keep getting this error:
org.codehaus.groovy.grails.web.servlet.mvc.exceptions.CannotRedirectException:
Cannot issue a redirect(..) here. The
response has already been committed
either by another redirect or by
directly writing to the response.
I am trying to do something like this where I redirect to another action on the controller then redirect back. Wondering why Grails is not allowing this.
//initial action and final redirect location
def showStuff = {
if (flash.neatStuff){
return render("found neat stuff")
} else if (params.email) {
return redirect(action:'getNeatStuff',params:[email:params.email, emailOnly:true])
}
return render("Unable to find stuff, use param")
}
def getNeatStuff = {
flash.neatStuff = new Date()
if (params.emailOnly){
redirect(action:'showStuff')
}
redirect(action:'someOtherPlace')
}
Ok, I had a total brain fart. I corrected the code below in case anyone runs into this same error. I was racking my brain looking at other things, but I just wasn't returning the redirect on the action.
def getNeatStuff = {
flash.neatStuff = new Date()
if (params.emailOnly){
return redirect(action:'showStuff')
}
redirect(action:'someOtherPlace')
}

Resources