Grails controller's beforeInterceptor - grails

I am trying to make it so that no matter what function of my controller is accessed, if the session has been nulled, it goes back to the log in page after you click ok on a modal that pops up saying the session has expired but I can't quite get it to work. Here are the first few methods of this controller:
def beforeInterceptor = {
[action:this.&checkSession()]
}
def checkSession() {
if (!session.user) {
render text: """<script type="text/javascript"> alert('Session expired. Please log in again.'); window.location.href = data.url;</script>""",
contentType: 'js'
}
}
def index() {
redirect (action: customerLogin)
}
def customerLogin = {
selectedBatch = null
}
def authenticate = {
def user = null
def possibleUsersList = User.findAllWhere(user_name: params.username)
possibleUsersList.each {
if (bcryptService.checkPassword(params.password, it.user_password))
user = it
}
if (user) {
session.user = user
greetingName = user.user_name
render(contentType: 'text/json') {
[success: true, url: createLink(controller: 'customer', action: 'custMainPage')]
}
}
else {
//def messages = ResourceBundle.getBundle('messages')
//def errorstring = bundle.getString("fatcaone.login.error")
//println "Login error: " + ${errorstring}
render (contentType: 'text/json') {
//["message": '<p>code=fatcaone.login.error</p>']
["message": '<p>Login or Password incorrect.</p>']
}
}
}
def logout = {
if (session.user != null) {
flash.message = "Goodbye ${session.user.fullName}"
session.user = null
}
redirect(action: customerLogin)
}

beforeInterceptor has been removed from Grails 3.0.
See https://github.com/grails/grails-core/issues/635 for a discussion of this.

Given that you want to keep your code as it is do:
def beforeInterceptor = {
[action:this.&checkSession()]
}
private def checkSession() {
if (!session.user) {
flash.error = 'Session expired. Please log in again.'
redirect(action: customerLogin)
return false
}
}
def index() {
redirect (action: customerLogin)
}
def customerLogin = {
selectedBatch = null
}
def authenticate = {
def user = null
def possibleUsersList = User.findAllWhere(user_name: params.username)
possibleUsersList.each {
if (bcryptService.checkPassword(params.password, it.user_password))
user = it
}
if (user) {
session.user = user
greetingName = user.user_name
render(contentType: 'text/json') {
[success: true, url: createLink(controller: 'customer', action: 'custMainPage')]
}
}
else {
//def messages = ResourceBundle.getBundle('messages')
//def errorstring = bundle.getString("fatcaone.login.error")
//println "Login error: " + ${errorstring}
render (contentType: 'text/json') {
//["message": '<p>code=fatcaone.login.error</p>']
["message": '<p>Login or Password incorrect.</p>']
}
}
}
def logout = {
if (session.user != null) {
flash.message = "Goodbye ${session.user.fullName}"
session.user = null
}
redirect(action: customerLogin)
}
And in your login page add:
<g:if test="${flash.error}">
<script type="text/javascript">
alert('${flash.error}');
</script>
</g:if>

Check this
def checkSession() {
if (session == null || session["loginId"] == null) {
render text: """<script type="text/javascript"> alert('Session expired. Please log in again.'); window.location.href = "${createLink(controller: 'test',action: 'logout')}";</script>""",
contentType: 'js';
return false;
}
}

Related

HTTP Status 404 - Grails

I was trying to get into "http://localhost:8080/Twillio/smsService/index" from Grails view.
and I get errors like below.
HTTP Status 404 - "/WEB-INF/grails-app/views/smsService/index.gsp" not found.
My codes used for SmsServiceController.groovy is below.
package twillio
class SmsServiceController {
def index () {}
def smsService
def twilioHttpEndpointBean
def read = { withFormat { html {} } }
def create = { SendSmsCommand cmd ->
def validMessage = cmd.validate();
log.debug "Incoming message is ${validMessage ? 'valid' : 'invalid'}"
log.debug "Format is ${request.format}"
withFormat {
json {
if (validMessage) {
def smsResponse
try {
smsResponse = smsService.send(cmd.destination, cmd.message)
render(contentType: "application/json") {
result(success: true)
}
} catch (Exception e) {
render(contentType: "application/json", status: 500) {
result(success: false, message: e.message)
}
}
} else {
render(contentType: "application/json", status: 500) { result(success: false) }
}
}
}
}
}
class SendSmsCommand {
String destination
String message
static constraints = {
message(size: 1..140)
}
}
You have to place an index.gsp at grails-app/views/smsService/index.gsp

springSecurityService.getCurrentUser() returning error No such property: id for class: java.lang.String

I have tried to add this code to the AdminLoginController to check the current user's Role.
def checkRole() {
User user = springSecurityService.getCurrentUser()
if(User.getRoleByUser(user.username).contains(Constants.ROLE_ADMIN)){
redirect uri:'/admin'
}else if(User.getRoleByUser(user.username).contains(Constants.ROLE_TWO)) {
redirect uri:'/two'
}else if(User.getRoleByUSer(user.username).contains(Constants.ROLE_THREE)){
redirect uri: '/three'
}else{
}
}
When I try to run the application it's showing the error below:
groovy.lang.MissingPropertyException: No such property: id for class: java.lang.String
The error is on the line User user = springSecurityService.getCurrentUser()
if (springSecurityService.isLoggedIn()) {
User user = securityService.getCurrentUser() //Note:- i used securityService not springSecurityService
List<Role> currentUserRoles = UserRole.findByUser(user).collect { it.role } as List
if(currentUserRoles.contains(Role.findByName(Constants.ROLE_ONE))) {
redirect(controller:'admin', action:'index')
} else if(currentUserRoles.contains(Role.findByName(Constants.ROLE_TWO))) {
redirect(controller:'two', action:'action')
} else if(currentUserRoles.contains(Role.findByName(Constants.ROLE_THREE))) {
redirect(controller:'three', action:'action')
}
} else {
redirect action: 'auth', params: params
}
}
Note:- userRole domain class links role and the user.

Spring UI RegisterController - No such property

I am using grails 2.3.4 with ":spring-security-ui:1.0-RC1" and ':spring-security-core:2.0-RC2' plugin. I have configured both plugins in the Config.groovy like that:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.SaaSTemplate.auth.Person'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.SaaSTemplate.auth.PersonRole'
grails.plugin.springsecurity.authority.className = 'com.SaaSTemplate.auth.Role'
//**********************************
// Spring Security UI Settings
//**********************************
//password validation of RegisterController.groovy
grails.plugin.springsecurity.ui.password.validationRegex='^.*(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!##$%^&]).*$' //example: 1Test#!!
grails.plugin.springsecurity.ui.password.minLength=8
grails.plugin.springsecurity.ui.password.maxLength=64
My RegisterController.groovy looks like that:
#Secured(['permitAll'])
class RegisterController extends grails.plugin.springsecurity.ui.RegisterController {
// override default value from base class
static defaultAction = 'index'
// override default value from base class
static allowedMethods = [register: 'POST']
def mailService
def messageSource
def saltSource
def index() {
def copy = [:] + (flash.chainedParams ?: [:])
copy.remove 'controller'
copy.remove 'action'
[command: new RegisterCommand(copy)] // here is where I get the exception!!!!
}
def register(RegisterCommand command) {
if (command.hasErrors()) {
render view: 'index', model: [command: command]
return
}
String salt = saltSource instanceof NullSaltSource ? null : command.username
def user = lookupUserClass().newInstance(email: command.email, username: command.username,
accountLocked: true, enabled: true)
RegistrationCode registrationCode = springSecurityUiService.register(user, command.password, salt)
if (registrationCode == null || registrationCode.hasErrors()) {
// null means problem creating the user
flash.error = message(code: 'spring.security.ui.register.miscError')
flash.chainedParams = params
redirect action: 'index'
return
}
String url = generateLink('verifyRegistration', [t: registrationCode.token])
def conf = SpringSecurityUtils.securityConfig
def body = conf.ui.register.emailBody
if (body.contains('$')) {
body = evaluate(body, [user: user, url: url])
}
mailService.sendMail {
to command.email
from conf.ui.register.emailFrom
subject conf.ui.register.emailSubject
html body.toString()
}
render view: 'index', model: [emailSent: true]
}
def verifyRegistration() {
def conf = SpringSecurityUtils.securityConfig
String defaultTargetUrl = conf.successHandler.defaultTargetUrl
String token = params.t
def registrationCode = token ? RegistrationCode.findByToken(token) : null
if (!registrationCode) {
flash.error = message(code: 'spring.security.ui.register.badCode')
redirect uri: defaultTargetUrl
return
}
def user
// TODO to ui service
RegistrationCode.withTransaction { status ->
String usernameFieldName = SpringSecurityUtils.securityConfig.userLookup.usernamePropertyName
user = lookupUserClass().findWhere((usernameFieldName): registrationCode.username)
if (!user) {
return
}
user.accountLocked = false
user.save(flush:true)
def UserRole = lookupUserRoleClass()
def Role = lookupRoleClass()
for (roleName in conf.ui.register.defaultRoleNames) {
UserRole.create user, Role.findByAuthority(roleName)
}
registrationCode.delete()
}
if (!user) {
flash.error = message(code: 'spring.security.ui.register.badCode')
redirect uri: defaultTargetUrl
return
}
springSecurityService.reauthenticate user.username
flash.message = message(code: 'spring.security.ui.register.complete')
redirect uri: conf.ui.register.postRegisterUrl ?: defaultTargetUrl
}
def forgotPassword() {
if (!request.post) {
// show the form
return
}
String username = params.username
if (!username) {
flash.error = message(code: 'spring.security.ui.forgotPassword.username.missing')
redirect action: 'forgotPassword'
return
}
String usernameFieldName = SpringSecurityUtils.securityConfig.userLookup.usernamePropertyName
def user = lookupUserClass().findWhere((usernameFieldName): username)
if (!user) {
flash.error = message(code: 'spring.security.ui.forgotPassword.user.notFound')
redirect action: 'forgotPassword'
return
}
def registrationCode = new RegistrationCode(username: user."$usernameFieldName")
registrationCode.save(flush: true)
String url = generateLink('resetPassword', [t: registrationCode.token])
def conf = SpringSecurityUtils.securityConfig
def body = conf.ui.forgotPassword.emailBody
if (body.contains('$')) {
body = evaluate(body, [user: user, url: url])
}
mailService.sendMail {
to user.email
from conf.ui.forgotPassword.emailFrom
subject conf.ui.forgotPassword.emailSubject
html body.toString()
}
[emailSent: true]
}
def resetPassword(ResetPasswordCommand command) {
String token = params.t
def registrationCode = token ? RegistrationCode.findByToken(token) : null
if (!registrationCode) {
flash.error = message(code: 'spring.security.ui.resetPassword.badCode')
redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
return
}
if (!request.post) {
return [token: token, command: new ResetPasswordCommand()]
}
command.username = registrationCode.username
command.validate()
if (command.hasErrors()) {
return [token: token, command: command]
}
String salt = saltSource instanceof NullSaltSource ? null : registrationCode.username
RegistrationCode.withTransaction { status ->
String usernameFieldName = SpringSecurityUtils.securityConfig.userLookup.usernamePropertyName
def user = lookupUserClass().findWhere((usernameFieldName): registrationCode.username)
user.password = springSecurityUiService.encodePassword(command.password, salt)
user.save()
registrationCode.delete()
}
springSecurityService.reauthenticate registrationCode.username
flash.message = message(code: 'spring.security.ui.resetPassword.success')
def conf = SpringSecurityUtils.securityConfig
String postResetUrl = conf.ui.register.postResetUrl ?: conf.successHandler.defaultTargetUrl
redirect uri: postResetUrl
}
protected String generateLink(String action, linkParams) {
createLink(base: "$request.scheme://$request.serverName:$request.serverPort$request.contextPath",
controller: 'register', action: action,
params: linkParams)
}
protected String evaluate(s, binding) {
new SimpleTemplateEngine().createTemplate(s).make(binding)
}
// static final passwordValidator = { String password, command ->
// if (command.username && command.username.equals(password)) {
// return 'command.password.error.username'
// }
//
// if (!checkPasswordMinLength(password, command) ||
// !checkPasswordMaxLength(password, command) ||
// !checkPasswordRegex(password, command)) {
// return 'command.password.error.strength'
// }
// }
static boolean checkPasswordMinLength(String password, command) {
def conf = SpringSecurityUtils.securityConfig
int minLength = conf.ui.password.minLength instanceof Number ? conf.ui.password.minLength : 8
password && password.length() >= minLength
}
static boolean checkPasswordMaxLength(String password, command) {
def conf = SpringSecurityUtils.securityConfig
int maxLength = conf.ui.password.maxLength instanceof Number ? conf.ui.password.maxLength : 64
password && password.length() <= maxLength
}
static boolean checkPasswordRegex(String password, command) {
def conf = SpringSecurityUtils.securityConfig
String passValidationRegex = conf.ui.password.validationRegex ?:
'^.*(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!##$%^&]).*$'
password && password.matches(passValidationRegex)
}
// static final password2Validator = { value, command ->
// if (command.password != command.password2) {
// return 'command.password2.error.mismatch'
// }
// }
}
class RegisterCommand {
String username
String email
String password
String password2
def grailsApplication
static constraints = {
username blank: false, validator: { value, command ->
if (value) {
def User = command.grailsApplication.getDomainClass(
SpringSecurityUtils.securityConfig.userLookup.userDomainClassName).clazz
if (User.findByUsername(value)) {
return 'registerCommand.username.unique'
}
}
}
email blank: false, email: true
password blank: false, validator: RegisterController.passwordValidator
password2 validator: RegisterController.password2Validator
}
}
class ResetPasswordCommand {
String username
String password
String password2
static constraints = {
password blank: false, validator: RegisterController.passwordValidator
password2 validator: RegisterController.password2Validator
}
}
As you can see I have just copied the original controller from the source code. Therefore the other classes ResetPasswordCommand and RegisterCommand are also included. However, I still get the exception:
ui.SpringSecurityUiService problem creating Person: com.TestApp.auth.Person : (unsaved)
Die Eigenschaft [firstName] des Typs [class com.TestApp.auth.Person] darf nicht null sein
Die Eigenschaft [lastName] des Typs [class com.TestApp.auth.Person] darf nicht null sein
errors.GrailsExceptionResolver MissingPropertyException occurred when processing request: [GET] /TestApp/register/index
No such property: format for class: TestApp.Register.RegisterCommand. Stacktrace follows:
groovy.lang.MissingPropertyException: No such property: format for class: TestApp.Register.RegisterCommand
at TestApp.Register.RegisterController.index(RegisterController.groovy:26)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Why do I get this exception? I have included the class RegisterCommand (as also in the original source) in my file?
I really appreciate your input!
UPDATE
I changed my method like that:
def index() {
def copy = [:] + (flash.chainedParams ?: [:])
copy.remove 'controller'
copy.remove 'action'
['controller', 'action', 'format'].each { copy.remove it }
[command: new RegisterCommand(copy)]
}
However, now I still cannot process the registration, I get:
....ui.SpringSecurityUiService problem creating Person: com.TestApp.auth.Person : (unsaved)
The property [firstName] of the type [class com.TestApp.auth.Person] cannot be null
The property [lastName] of the type [class com.TestApp.auth.Person] cannot be null
format is added in the UrlMapping as an optional field.
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
So you would end up removing that from the map as done for action and controller.
//index action
['controller', 'action', 'format'].each { copy.remove it }
Another option will be to explicitly use bindData to avoid this collision
//index action
RegisterCommand cmd = new RegisterCommand()
bindData copy, cmd

grails loginfilter blocks css

I've some troubles with my loginfilter in grails. If there is no session, it redirects me to the login page, but it blocks the css.
class LoginFilters {
def filters = {
loginCheck(controller: '*', action: '*') {
before = {
println("USER: "+session.user)
println("ActionName: "+actionName)
println("Controller: "+controllerName)
if (session.user == null) {
println("Redirecting to Loginpage")
render(view: '/index');
return true
}else{
return true
}
}
}
}
}
Where is my problem?

idiom for save and update methods in grails

Are there in any idioms in grails which help us with saving domain objects ?
For example
i may want to do something like
if(candidate.hasErrors || !candidate.save)
{
candidate.errors.each {
log it
}
However i do not want to spread the logic across all the places i do domainObject.save.
I also do not want seperate class like say repo to which I pass this domainObject and put in this logic
Thanks
Sudarshan
Here's a service method that I've used to validate and save, but log resolved validation messages on failure. It's helpful to use this instead of just println error or log.warn error since the toString() for error objects is very verbose and you just want to see what would be displayed on the GSP:
class MyService {
def messageSource
def saveOrUpdate(bean, flush = false) {
return validate(bean) ? bean.save(flush: flush) : null
}
boolean validate(bean) {
bean.validate()
if (bean.hasErrors()) {
if (log.isEnabledFor(Level.WARN)) {
def message = new StringBuilder(
"problem ${bean.id ? 'updating' : 'creating'} ${bean.getClass().simpleName}: $bean")
def locale = Locale.getDefault()
for (fieldErrors in bean.errors) {
for (error in fieldErrors.allErrors) {
message.append("\n\t")
message.append(messageSource.getMessage(error, locale))
}
}
log.warn message
}
bean.discard()
return false
}
return true
}
And here's an example in a controller:
class MyController {
def myService
def actionName = {
def thing = new Thing(params)
if (myService.saveOrUpdate(thing)) {
redirect action: 'show', id: thing.id
}
else {
render view: 'create', model: [thing: thing]
}
}
}
Edit: It's also possible to add these methods to the MetaClass, e.g. in BootStrap.groovy:
class BootStrap {
def grailsApplication
def messageSource
def init = { servletContext ->
for (dc in grailsApplication.domainClasses) {
dc.metaClass.saveOrUpdate = { boolean flush = false ->
validateWithWarnings() ? delegate.save(flush: flush) : null
}
dc.metaClass.validateWithWarnings = { ->
delegate.validate()
if (delegate.hasErrors()) {
def message = new StringBuilder(
"problem ${delegate.id ? 'updating' : 'creating'} ${delegate.getClass().simpleName}: $delegate")
def locale = Locale.getDefault()
for (fieldErrors in delegate.errors) {
for (error in fieldErrors.allErrors) {
message.append("\n\t")
message.append(messageSource.getMessage(error, locale))
}
}
log.warn message
delegate.discard()
return false
}
return true
}
}
}
}
This depends on a 'log' variable being in scope, which will be true in any Grails artifact. This changes the controller usage slightly:
class MyController {
def actionName = {
def thing = new Thing(params)
if (thing.saveOrUpdate()) {
redirect action: 'show', id: thing.id
}
else {
render view: 'create', model: [thing: thing]
}
}
}
As a metaclass method it may make more sense to rename it, e.g. saveWithWarnings().

Resources