|
Hello,
I'm discovering the Spring Security plugins with pleasure, since they almost take care already of everything I wished for. Unfortunately, I still have a newbie question: I modified the User class autogenerated by the spring-security-core plugin to include an email and a "realname" properties. For registering new users, the email was actually expected by the spring-security-ui plugin, so that was okay. But my realname property is declared via constraints as "not null", and I had to add it to the index view of the register controller.
Now, I'm looking for tips on the best route to take. I tried modifying the RegisterCommand class in the extended RegisterController installed by the plugin, but I get other errors later, so I expect I'm missing a simpler way to do this.
Could anyone give me hints or pointers ? I read in the doc about adding a fullName property to the UserDetails implementation, but I have absolutely no clue how and where to do that :-/ Thanks in advance. -- Alain Perry |
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 Alain Perry wrote: > Now, I'm looking for tips on the best route to take. I tried modifying the > RegisterCommand class in the extended RegisterController installed by the > plugin, but I get other errors later, so I expect I'm missing a simpler > way to do this. This is what I did. Acutally I reimplemented the RegisterCommand, and overrode the "index" and "register" actions of the RegisterController so they use my RegisterCommands, and to pick up the added field into the User domain class. Cheers, Marcus -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAkxs8HMACgkQXjXn6TzcAQm/QgCgy6+x16AmsITC+F5oxlzYucCM JH8AoJ1HNbpdwXV1679gWU5OKZZnn0HS =pHx3 -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
Thank you for your answer.
Would you mind sharing with the list ? As I said, when I tried to do it this way, I encountered many errors, one of which I wasn't able to trace down. Anyway, I might try again tonight and add code snippets and said error to this thread. Thank you. -- Alain Perry On Thu, Aug 19, 2010 at 10:50 AM, Marcus Better <[hidden email]> wrote: -----BEGIN PGP SIGNED MESSAGE----- |
|
OK, no idea what I did wrong last time, but it sure does work like a charm after re-implementing RegisterCommand and the index and register actions. It even allows me to modify the passwordValidator closure. All is well and sorry for the noise.
Thanks for the help. -- Alain Perry On Thu, Aug 19, 2010 at 11:36 AM, Alain Perry <[hidden email]> wrote: Thank you for your answer. |
We tried extending RegisterController.groovy by copying the actions index and register, and the command object RegisterCommand, like this: package com.futboloco
import org.codehaus.groovy.grails.plugins.springsecurity.ui.RegistrationCode
import org.codehaus.groovy.grails.plugins.springsecurity.NullSaltSource
class RegisterController extends grails.plugins.springsecurity.ui.RegisterController {
static defaultAction = 'index'
def mailService
def saltSource
def index = {
[command: new RegisterCommand()]
}
def register = { RegisterCommand command ->
if (command.hasErrors()) {
render view: 'index', model: [command: command]
return
}
String salt = saltSource instanceof NullSaltSource ? null : command.username
String password = springSecurityService.encodePassword(command.password, salt)
def user = lookupUserClass().newInstance(email: command.email, username: command.username,
password: password, accountLocked: true, enabled: true)
if (!user.validate() || !user.save()) {
// TODO
}
def registrationCode = new RegistrationCode(username: user.username).save()
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]
}
class RegisterCommand {
String username
String email
String password
String password2
String city
static constraints = {
username blank: false, validator: { value, command ->
if (value) {
def User = AH.application.getDomainClass(
SpringSecurityUtils.securityConfig.userLookup.userDomainClassName).clazz
if (User.findByUsername(value)) {
return 'registerCommand.username.unique'
}
}
}
email blank: false, email: true
password blank: false, minSize: 8, maxSize: 64, validator: RegisterController.passwordValidator
password2 validator: RegisterController.password2Validator
}
}
}As you see, we tried adding a field for 'City' (we also added this to our User domain class, of course) Unfortunately, we have now ended up with this error: grails.validation.ValidationException: Validation Error(s) occurred during save():
- Field error in object 'com.User' on field 'city': rejected value [null]; codes [com.User.city.nullable.error.com.User.city,com.User.city.nullable.error.city,com.User.city.nullable.error.java.lang.String,com.User.city.nullable.error,user.city.nullable.error.com.User.city,user.city.nullable.error.city,user.city.nullable.error.java.lang.String,user.city.nullable.error,com.User.city.nullable.com.User.city,com.User.city.nullable.city,com.User.city.nullable.java.lang.String,com.User.city.nullable,user.city.nullable.com.User.city,user.city.nullable.city,user.city.nullable.java.lang.String,user.city.nullable,nullable.com.User.city,nullable.city,nullable.java.lang.String,nullable]; arguments [city,class com.User]; default message [The field [{0}] in the class [{1}] cannot be null].. any idea on how we approach this task of extending our RegisterController with our custom field 'City'? We feel a bit lost.. ps. we also added a city entry field in the corresponding view |
|
grails 1.3.7, Spring Security UI 0.1.2:
Okaaaaaaaay, here we go. Our stuff now works! That is, we have successfully modified our class RegisterController so that it extends grails.plugins.springsecurity.ui.RegisterController (see code below). We have modified it so that the user is now also asked to tell which city he lives in. The city field is then saved to the database. To make it work, we went through our RegisterController and added 'city' all the places that we saw the other four fields (username, password, password again, email). Then we added city to the constraints section of the user domain class. The constraint was 'city nullable : true'). Then we modified the index.gsp view to show a field to which the user can enter his city (see code below). Our code: ~/com.futboloco/grails-app/controllers/com/futboloco/RegisterController
package com.futboloco
import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
import org.codehaus.groovy.grails.plugins.springsecurity.NullSaltSource
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import org.codehaus.groovy.grails.plugins.springsecurity.ui.RegistrationCode
class RegisterController extends grails.plugins.springsecurity.ui.RegisterController {
static defaultAction = 'index'
def mailService
def saltSource
def index = {
[command: new RegisterCommand()]
}
def register = { RegisterCommand command ->
if (command.hasErrors()) {
render view: 'index', model: [command: command]
return
}
println("CITY:" + command.city)
String salt = saltSource instanceof NullSaltSource ? null : command.username
String password = springSecurityService.encodePassword(command.password, salt)
def user = lookupUserClass().newInstance(city: command.city, email: command.email, username: command.username,
password: password, accountLocked: true, enabled: true)
if (!user.validate() || !user.save()) {
// TODO
}
def registrationCode = new RegistrationCode(username: user.username).save()
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]
}
class {
String username
String email
String password
String password2
String city
static constraints = {
username blank: false, validator: { value, command ->
if (value) {
def User = AH.application.getDomainClass(
SpringSecurityUtils.securityConfig.userLookup.userDomainClassName).clazz
if (User.findByUsername(value)) {
return 'registerCommand.username.unique'
}
}
}
email blank: false, email: true
password blank: false, minSize: 8, maxSize: 64, validator: RegisterController.passwordValidator
password2 validator: RegisterController.password2Validator
}
}
}
~/com.futboloco/grails-app/views/register/index.jsp :
<head>
<meta name='layout' content='register'/>
<title><g:message code='spring.security.ui.register.title'/></title>
</head>
<body>
<p/>
<s2ui:form width='650' height='300' elementId='loginFormContainer'
titleCode='spring.security.ui.register.description' center='true'>
<g:form action='register' name='registerForm'>
<g:if test='${emailSent}'>
<br/>
<g:message code='spring.security.ui.register.sent'/>
</g:if>
<g:else>
<br/>
<table>
<tbody>
<s2ui:textFieldRow name='username' labelCode='user.username.label' bean="${command}"
size='40' labelCodeDefault='Username' value="${command.username}"/>
<s2ui:textFieldRow name='email' bean="${command}" value="${command.email}"
size='40' labelCode='user.email.label' labelCodeDefault='E-mail'/>
<s2ui:passwordFieldRow name='password' labelCode='user.password.label' bean="${command}"
size='40' labelCodeDefault='Password' value="${command.password}"/>
<s2ui:passwordFieldRow name='password2' labelCode='user.password2.label' bean="${command}"
size='40' labelCodeDefault='Password (again)' value="${command.password2}"/>
<s2ui:textFieldRow name='city' labelCode='user.city.label' bean="${command}"
size='40' labelCodeDefault='City' value="${command.city}"/>
</tbody>
</table>
<s2ui:submitButton elementId='create' form='registerForm' messageCode='spring.security.ui.register.submit'/>
</g:else>
</g:form>
</s2ui:form>
<script>
$(document).ready(function() {
$('#username').focus();
});
</script>
</body>
~/com.futboloco/grails-app/domain/com/futboloco/User.Groovy :
package com
class User {
String username
String password
String city
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static constraints = {
username blank: false, unique: true
password blank: false
city nullable: true
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
}
|
|
In reply to this post by frederik-
You mentioned that you were able to overwrite the passwordValidator. I am a little surprise since it is a static final, which I would think you can not overwrite. I actually tried it and was not successful.
|
| Powered by Nabble | Edit this page |
