Quantcast

Using spring security UI with customized user class

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Using spring security UI with customized user class

Alain Perry
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using spring security UI with customized user class

Marcus Better
-----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


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using spring security UI with customized user class

Alain Perry
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-----
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



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using spring security UI with customized user class

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

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




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using spring security UI with customized user class

frederik-
Alain Perry wrote
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.
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using spring security UI with customized user class

loldrup
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
	}
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using spring security UI with customized user class

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