Grails access current environment from within config.groovy - grails

Using the Grails OAuth plugin requires that an absolute callback URL be provided in Config.groovy. However I have different serverURLs for each environment.
Is there a way to get the current environment from inside Config.groovy, here's an example of what I want to do:
def devServerUrl = 'http://dev.example.com'
def prodServerUrl = 'http://prod.example.com'
def currentServerUrl = grailsApplication.metadata.environment == 'development' ? devServerUrl : prodServerUrl;
environments {
development {
grails {
serverURL = devServerUrl
}
}
production {
grails {
serverURL = prodServerUrl
}
}
}
oauth {
providers {
runkeeper {
api = RunKeeperApi
key = 'key'
secret = 'secret'
callback = currentServerUrl + '/oauth/runkeeper/callback'
}
}
}
Any ideas? Thanks!

Try this:
def currentServerUrl = Environment.current.name == 'development' ? devServerUrl : prodServerUrl;

I think it is cleaner to set different grails.serverURL for each environment and then do:
callback = "${grails.serverURL}/oauth/runkeeper/callback"

Related

Get environment specific server app URL in grails service

I want to get the server URL in Groovy, if I deploy in my local environment I want it to link to localhost:8080 but on the test and live environment it should be different. Is there any way to do this in my Groovy service?
Your Config.groovy
environments {
development {
grails.config.serverAppURL = YOUR_DEVELOPMENT_MODE_APP_URL
}
production {
grails.config.serverAppURL = YOUR_PRODUCTION_MODE_APP_URL
}
test {
grails.config.serverAppURL = YOUR_TEST_MODE_APP_URL
}
}
Access this url in your service
Class MyService {
def grailsApplication // inject this service
def testMethod(){
def appUrl = grailsApplication.config.serverAppURL // getting url here
println appUrl
}
}
Configuration of your grails application
environments {
development {
grails.server.url = "localhost:8080"
}
production {
grails.server.url = "http://example.com"
}
test {
grails.server.url = "http://production.com"
}
}
You can get your server URL using Holders like this.
class something {
String getAppURL() {
String serverURL = Holders.flatConfig.get("grails.server.url")
return serverURL
}
}

Dynamic Quartz Configuration in Grails 3

In Grails 2, we had the following block of code in our Config.groovy file. The ConfigurationManagement class did a runtime lookup in a Configuration Management Database to determine if the quartz.autoStartup parameter should be true or false. We also used similar configuration to load additional Quartz properties.
quartz {
def autoStartupOnTheseServers = ConfigurationManagement.getValue("myApp.quartz.autoStartupOnTheseServers", "").split(",")
if ( autoStartupOnTheseServers.any { it.trim().toUpperCase() == hostName.toUpperCase() } ) {
autoStartup = true
}
else {
autoStartup = false
}
// Default for clustering (jdbcStore) has to be "false" so the app will run locally.
// Clustering (jdbcStore) will be true for DEV, TEST, QA, and PROD (set by Configuartion Management).
jdbcStore = ConfigurationManagement.getValue("myApp.quartz.jdbcStore", "false").toBoolean()
// don't set the props if not enabling quartz clustering...causes an exception.
if(jdbcStore == true) { props(quartzProps) }
}
In Grails 3, similar code used in application.groovy doesn't work and there isn't any facility for conditionals that I can find for application.yml. Is there any way in Grails 3 to do a similar dynamic configuration?
In Grails 3, it seems that you can't set these values directly, but you can declare a local variable and use that to set the property. So, for my example above, the following works:
def extServerList = ConfigurationManagement.getValue("myApp.quartz.autoStartupOnTheseServers", "").split(",")
def extAutoStartup = extServerList.any { it.trim().toUpperCase() == hostName.toUpperCase() }
def extJdbcStore = ConfigurationManagement.getValue("myApp.quartz.jdbcStore", "false").toBoolean()
quartz {
autoStartupOnTheseServers = extServerList
autoStartup = extAutoStartup
jdbcStore = extJdbcStore
}

Not able to use grails database session plugin with mongodb

We are using grails 2.3.5 app with mongodb (no hibernate installed). I had forked & modified grails database session plugin with HQL queries to use simple queries so as to support mongodb.
Then when I'm trying to login via ajax, it fails. By fail, I mean that, session in created & persisted to the database but not able to login. When I enabled to logs, I saw cookies is present in the request path /j_spring_security_check after authentication but is not available after redirect i.e. in path /login/ajaxSuccess which causing authentication to be treated as false & a new session is created.
Our URL mapping config looks like this: (Does not matters)
"/$controller/$action?/$id?(.$format)?" {
constraints {
}
}
"/v2/$customController/action/$customAction" {
controller = {
return params.customController?.toUpperCamelCase()
}
action = {
return params.customAction?.toUpperCamelCase()
}
}
"/v2/$resource/$resourceId?/$subResource?/$subResourceId?" {
controller = {
if (params.subResource) {
return params.subResource.toUpperCamelCase()
}
return params.resource.toUpperCamelCase()
}
action = {
Map actionMethodMap = [GET: params.resourceId ? "show" : "index", POST: "save", PUT: "update", DELETE: "delete"]
return actionMethodMap[request.method.toUpperCase()]
}
id = {
if (params.subResource && params.subResourceId) {
return params.subResourceId
}
return params.resourceId
}
}
Our configuration looks like this for spring security:
grails.plugins.springsecurity.authority.className = 'com.test.Role'
grails.plugins.springsecurity.userLookup.userDomainClassName = 'com.test.User'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'com.test.UserRole'
grails.plugins.springsecurity.useSessionFixationPrevention = true
//grails.plugins.springsecurity.redirectStrategy.contextRelative = true
grails.plugins.springsecurity.successHandler.defaultTargetUrl = "/app/ng/index.html"
grails.plugins.springsecurity.auth.loginFormUrl = "/app/ng/index.html#/auth/signin"
grails.plugins.springsecurity.auth.ajaxLoginFormUrl = "/v2/login/action/auth-ajax"
grails.plugins.springsecurity.ui.encodePassword = false
grails.plugins.springsecurity.controllerAnnotations.staticRules = [
'/j_spring_security_switch_user': ['ROLE_ADMIN'],
'/ck/standard/filemanager': ['ROLE_ADMIN'],
'/ck/standard/uploader': ['ROLE_ADMIN'],
'/ck/ofm/filemanager': ['ROLE_ADMIN'],
'/ck/ofm/filetree': ['ROLE_ADMIN'],
'/quartz/**': ["ROLE_ADMIN"],
'/**' : ['IS_AUTHENTICATED_ANONYMOUSLY']
]
Other than this, grails.serverURL config is commented for all environments to support wildcard subdomain.
Using:
Spring Security Core plugin version 1.2.7.3
Cookie plugin version 0.51
Webxml plugin version 1.4.1
Mongodb plugin version 2.0.1

Render from controller is working fine in development but not in test

I have the following code in my grails app:
def list () {
def roles = principal.authorities*.authority
def page = roles.contains("ROLE_ADMIN")? "allcolors": "usercolors"
if (params.sort == "latest" || params.sort == null) {
logger.debug("came in if");
render view: page, model: [colorlist: colorService.colorList()]
}
else
render view: page, model: [colorlist: colorService.colorListForUser()]
}
When I run my application with grails run-app the above code works fine. However, when I deploy the war file created by grails test war target/myapp.war the above code does not work and errors with "Page not found" even though the debug statement came in if still gets printed.
I've tried to run this app in development with grails test run-app as well but even then the above does not work. Interestingly, when I run the app in prod mode (grails prod run-app) everything works fine as well. So it is certainly something to do with the test environment
Also, to ensure there aren't any data discrepancies I've changed dev test and prod to point at the same development database.
Could it be that my app has some special setting for test environment that I'm failing to see ...which would cause "render" to not work?
My environment looks like this:
environments {
development {
grails.logging.jul.usebridge = true
}
test {
grails.logging.jul.usebridge = true
}
production {
grails.logging.jul.usebridge = false
}
}
And DB config looks like this:
environments {
development {
dataSource {
dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:mysql://localhost/myapp?useUnicode=yes&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8"
username = "root"
password = ""
}
hibernate {
}
}
test {
dataSource {
dbCreate =
url = "jdbc:mysql://localhost/myapp?useUnicode=yes&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8"
username = "root"
password = ""
properties {
}
hibernate {
}
}
}
production {
dataSource {
dbCreate = "create-drop"
url = "jdbc:mysql://localhost/myapp?useUnicode=yes&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8"
username = "root"
password = ""
}
}
}
How can I resolve this or troubleshoot it further??
run-app runs with the default "development" data source, which is not to be confused with the "test" environment. Check your Config.groovy (edit: and DataSource.groovy) and make sure you have test { } configured within your environments.
More info can be found in the grails documentation here:
http://www.grails.org/Environments

Logic block in Grails URLMappings

My site has urls like 'http://someRandomUsername.mysite.com'.
Sometimes users will try urls like
'http://www.someRandomeUsername.mysite.com'. I'd like to have some
logic in my url mappings to deal with this.
With the mappings below when I hit the page , with or without the
unneeded www, I get:
2012-03-01 14:52:16,014 [http-8080-5] ERROR [localhost].[/ambit] -
Unhandled exception occurred whilst decorating page
java.lang.IllegalArgumentException: URL mapping must either provide a
controller or view name to map to!
Any idea how to accomplish this? The mapping is below.
Thanks!
Jason
static mappings = {
name publicMap: "/$action?/$id?" {
def ret = UrlMappings.check(request)
controller = ret.controller
userName = ret.userName
}
}
static check =
{ request ->
def tokens = request?.serverName?.split(/\./) as List ?: []
def ret = [controller:'info']
if(tokens.size() > 3 && token[0] == 'www')
{
ret.userName = tokens[1]
ret.controller = 'redirect'
ret.action = 'removeWWW'
}
else if(tokens.size() == 3)
{
ret.userName = tokens[0]
ret.controller = 'info'
}
return ret
}
Honestly, like DmitryB said, the best way to do this is via the web server, whether it's IIS, Apache, or Tomcat.
Having said that, I feel the best way to accomplish this in Grails would be using filters.
You could create something like this in your ~/conf directory:
public class StripFilters {
def filters = {
stripWWWFilter(controller: '*', action: '*') {
before = {
def tokens = request.serverName.tokenize(/\./) ?: []
if(tokens.size() > 3 && tokens[0] == 'www') {
def url = request.request.requestURL.toString().replace('www.', '')
redirect([url:url, params: [userName: tokens[1]], permanent: true])
return false
}
}
}
}
}
This should do the trick.

Resources