Grails 2.3.8 check url mappings for string occurence - grails

I am trying to map the following
//localhost:8080/user/login/&debug=1
...
//localhost:8080/user/&debug=1
If there is any occurrence of string '&debug=1' then execute some-controller's action.

You can use a filter to do the redirect when required.
class DebugFilters {
def filters = {
debugCheck(controller: '*', action: '*') {
before = {
if (params.debug == '1') {
redirect(controller: 'some', action: 'debug')
return false
}
}
}
}
}
If you want to just switch between controllers and actions for a particular url mapping then you can also use a url mapping as below, instead of the filter altogether:
//UrlMappings.groovy
"/user/login" {
controller = { params.debug == '1' ? 'some' : 'user' }
action = { params.debug == '1' ? 'debug': 'index' }
// Note the use of a closure in ternary operations
// params is available in a closure (delegated)
// because it is not available in by default
}

You could use a URLMapping like this
"/**&debug=1"(controller:"defaultDebug"){
action = [GET: "show"]
}
By using the double wildcard you can catch anything that ends with &debug=1

Related

Grails 3 How to access a namespace from an interceptor

I set up namespaces in my UrlMappings.groovy as:
"/usa_az/$controller/$action/$id?(.${format})?"(namespace: 'usa_az')
"/usa_ms/$controller/$action/$id?(.${format})?"(namespace: 'usa_ms')
Is there a way to do something like:
class NameSpaceInterceptor {
NameSpaceInterceptor(){
matchAll() //match all controllers
}
//Change the name of the view to find it in state-specific folder in views
boolean after() {
if(*controller.namespace* == 'usa_az' ){
view = "/usa_az/$view"
} else if (*controller.namespace* == 'usa_ms' ){
view = "/usa_ms/$view"
}
true
}
}
How do I find the handle to controller or more importantly the namespace in this interceptor?
I actually did something along the lines of this:
boolean before() {
if (controllerNamespace == "admin") {
}
}
in one of my interceptors, so the answer should be via controllerNamespace.

Can Grails route requests to different controller by *method*?

I have a URL that I'd like to handle with different controllers depending on the method. Is there a way to do this via UrlMappings?
Using two different mappings for the same URL doesn't work (the second overwrites the first)...
Untested, but can you try with the below mapping:
"/myurl" {
if(params.method == "doThis"){
controller = "doThis"
action = "doThisAction"
} else if(params.method == "doThat"){
controller = "doThat"
action = "doThatAction"
}
}
Assuming,
http://<appserver>/myurl?method=doThis
http://<appserver>/myurl?method=doThat
UPDATE
When referring to HTTP Methods you can use filter (where we have request available) as below:
class RoutingFilters{
def filters = {
routingCheck(uri: '/myurl/**' ) {
before = {
if(request.method == 'GET'){
redirect(controller: 'doThis', action: 'doThis')
}
if(request.method == 'POST'){
redirect(controller: 'doThat', action: 'doThat')
}
//So on and so forth for PUT and DELET
return false
}
}
}
}
provided the url mapping would look something like:
//defaulting to "doThis" or any other "valid" controller as dummy
"/myurl/$id?"(controller: 'doThis')

grails url mapping for google ajax search

This is probably a very simple problem but for the life of me I can't get it to work.
I need to redirect google requests for ajax generated code to return a html template for indexing
I have the following in my urlmappings.conf
"/?_escaped_fragment_=$id"(controller:"google",action:"getOfferDetails")
However if I enter mysite?_escaped_fragment_=200 in the browser the controller is not called
If however I enter mysite_escaped_fragment=200 the controller is called and the action executed.
Any suggestions would be greatly appreciated.
Thanks
Ash
You can not use '?' char in the route matching i.e. it will be ignored.
Use this filter instead (put this class in the config folder w/ fileName CrawlerFilters.groovy):
class CrawlerFilters {
def filters = {
google(controller: '*', action: '*') {
before = {
boolean isCrawler = webRequest.params._escaped_fragment_ != null
if (isCrawler && !request._alreadyForwarded) {
request._alreadyForwarded = true
forward controller: 'google', action: 'getOfferDetails'
}
}
}
}`

How to redirect to external url using filters when controller does not exist in current app

I have the following filter that in app1 that is supposed to redirect to an external app (app2).
class MyFilters {
def userService
def springSecurityService
def filters = {
all(controller: '*', action: '*') {
before = {
String userAgent = request.getHeader('User-Agent')
int buildVersion = 0
// Match "app-/{version}" where {version} is the build number
def matcher = userAgent =~ "(?i)app(?:-\\w+)?\\/(\\d+)"
if (matcher.getCount() > 0)
{
buildVersion = Integer.parseInt(matcher[0][1])
log.info("User agent is from a mobile with build version = " + buildVersion)
log.info("User agent = " + userAgent)
String redirectUrl = "https://anotherdomain.com"
if (buildVersion > 12)
{
if (request.queryString != null)
{
log.info("Redirecting request to anotherdomain with query string")
redirect(url:"${redirectUrl}${request.forwardURI}?${request.queryString}",params:params)
}
return false
}
}
}
after = { model ->
if (model) {
model['currentUser'] = userService.currentUser
}
}
afterView = {
}
}
}
}
A problem occurs when the request to app1 contains a URI where the controller name does not exist in app1 (But does in app2 where I want to redirect to).
How can I redirect requests to app2 with same URI appended? (regardless if they exist in app1 or not).
I suspect filter's are not the correct solution as it will never enter them if the controller does not exist in app.
Ideally, I need a solution that can be implmented via code and not apache.
Thanks
Define a general purpose redirect controller like this:
class RedirectController {
def index() {
redirect(url: "https://anotherdomain.com")
}
}
In UrlMappings, point 404 to this controller:
class UrlMappings {
static mappings = {
......
"404"(controller:'redirect', action:'index')
......
}
}
Actually you can define all the redirect relationships here instead of deal with filter.
You can set the scope of a filter by URI as well as by controller name, try:
def filters = {
all(uri:'/**') {

How to restrict user from accessing a particular action of a controller?

def filters = {
loginCheck(controller:'*', action:'*') {
before = {
if(!session.user && !session.merchants)
{
redirect(action:'login')
return false
}
}}
That was my filter for login security. And below is interceptor in action for restricting user from search action. But both are not working. Can any one tell what the mistake is?
def beforeInterceptor = [action:this.&checkUser,Only:'search']
def scaffold = true
def checkUser()
{
if (session.user)
{
redirect(action:"search")
}
if(session.merchants)
{
redirect(action:"toIndex")
flash.message="You are not valid user for this action"
return false
}
}
There's a really nice shorthand that you can apply directly to actions (if you're not using filters):
#Secured(['ROLE_USER'])
def search = {
}
You can give every user ROLE_USER and simply require that role.
actually you filter should work as it is set for every controller and every action.
here is the grails example from the reference:
class SecurityFilters {
def filters = {
loginCheck(controller:'*', action:'*') {
before = {
if(!session.user && !actionName.equals('login')) {
redirect(action:'login')
return false
}
}
}
}
}
I worked with this one and it worked for me.
What I'm not sure is about the session.merchants in your code.
What is this ?
Did you follow this:
To create a filter create a class that
ends with the convention Filters in
the grails-app/conf directory.
Edit:
If you use spring security you don't need to add a filter or interceptor.
check the user guide: http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/index.html
you can configure it with url mappings or annotations.
ex.
grails.plugins.springsecurity.controllerAnnotations.staticRules = [
'/js/admin/**': ['ROLE_ADMIN'],
'/someplugin/**': ['ROLE_ADMIN']
]
EDIT 2:
To get the logged in user use:
def authenticateService
...
def action{
def user = authenticateService.principal()
def username = user?.getUsername()
...

Resources