Changeset 1144
- Timestamp:
- Nov 16, 2010, 2:57:22 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/dbnp/authentication/UserRegistrationController.groovy
r1138 r1144 17 17 18 18 class UserRegistrationController { 19 static int DAYS_BEFORE_EXPIRY = 3; 20 static int DAYS_BEFORE_EXPIRY_ADMIN = 365; 21 19 22 def springSecurityService 20 23 def authenticationService … … 30 33 * for confirmation 31 34 */ 32 def add = { 33 if( !params.username || !params.email ) { 34 flash.message = "You must enter a username and provide an email address" 35 render(view: "index", model: [username: params.username, email: params.email]) 36 return 37 } 38 39 // Check whether this username already exists 40 if( SecUser.findByUsername( params.username ) ) { 41 flash.message = "Username already exists" 42 render(view: "index", model: [username: params.username, email: params.email]) 43 return 44 } 35 def add = { RegisterCommand command -> 36 37 command.validate() 38 39 if (command.hasErrors()) { 40 def addSendUserLink = false; 41 42 // Check the errors and append a link if needed 43 command.errors.allErrors.each { 44 if( it.code == "registerCommand.username.notyetconfirmed" ) { 45 addSendUserLink = true; 46 } 47 } 48 49 flash.message = ""; 50 render(view: "index", model: [username: params.username, email: params.email, command: command, addSendUserLink: addSendUserLink]) 51 return 52 } 45 53 46 54 // Generate a random password … … 48 56 49 57 def user = new SecUser( 50 username : params.username,58 username : params.username, 51 59 email: params.email, 52 60 password: springSecurityService.encodePassword(password, params.username), … … 62 70 flash.message = "" 63 71 64 // Create links for the user and administrator to click on. These codes are built from 65 // the username and encrypted password. They do not provide 100% security, since the codes 66 // could be broken, but it is enough for the confirmation step 67 def userCode = ( user.username + user.password + 'user' ).encodeAsMD5(); 68 def adminCode = ( user.username + user.password + 'admin' ).encodeAsMD5(); 69 def userLink = createLink( controller: 'userRegistration', action: 'confirmUser', params: [id: user.id, code: userCode], absolute: true ) 70 def adminLink = createLink( controller: 'userRegistration', action: 'confirmAdmin', params: [id: user.id, code: adminCode], absolute: true ) 72 sendUserConfirmationMail( user, password ); 73 sendAdminConfirmationMail( user ); 74 75 // Give the user a nice welcome page 76 } 77 78 def sendUserConfirmation = { 79 def user = SecUser.findByUsername( params.username ); 80 if( !user ) { 81 flash.message = "No user with this username is found in the database."; 82 render(view: "index", model: [username: params.username]) 83 } 84 if( user.userConfirmed ) { 85 flash.message = "This user has already been confirmed"; 86 render(view: "index", model: [username: params.username]) 87 } 88 89 // Remove old registration codes 90 RegistrationCode.deleteByUser(user); 91 92 // Create a new password 93 def password = this.generatePassword(8) 94 user.password = springSecurityService.encodePassword(password, user.username) 95 96 // Send a message 97 sendUserConfirmationMail(user, password); 98 99 flash.message = "A new confirmation email has been sent to your registered email address"; 100 render(view: "index", model: [username: params.username]) 101 } 102 103 private sendUserConfirmationMail( SecUser user, String password ) { 104 def userCode = new RegistrationCode(userId: user.id, expiryDate: new Date() + UserRegistrationController.DAYS_BEFORE_EXPIRY).save( flush: true ); 105 def userLink = createLink( controller: 'userRegistration', action: 'confirmUser', params: [code: userCode.token], absolute: true ) 71 106 72 107 // Send an email to the user 73 108 try { 74 109 sendMail { 75 to params.email110 to user.email 76 111 subject "Registration at GSCF" 77 html g.render(template:'/email/registrationConfirmationUser', model:[username: user.username, password: password, link: userLink])112 html g.render(template:'/email/registrationConfirmationUser', model:[username: user.username, password: password, expiryDate: userCode.expiryDate, link: userLink]) 78 113 } 79 114 } catch(Exception e) { 80 115 log.error "Problem sending email $e.message", e 81 116 flash.message = 'Email could not be sent' 82 } 117 return false 118 } 119 120 return true 121 } 122 123 private sendAdminConfirmationMail( SecUser user ) { 124 def adminCode = new RegistrationCode(userId: user.id, expiryDate: new Date() + UserRegistrationController.DAYS_BEFORE_EXPIRY_ADMIN).save(flush: true) 125 def adminLink = createLink( controller: 'userRegistration', action: 'confirmAdmin', params: [code: adminCode.token], absolute: true ) 83 126 84 127 // Send an email to the administrators 85 128 try { 129 // Determine administrator email addresses 86 130 sendMail { 87 131 to "gscfproject@gmail.com" … … 92 136 log.error "Problem sending email $e.message", e 93 137 flash.message = "Email could not be sent to administrators" 94 } 95 96 // Give the user a nice welcome page97 [username: user.username, password: password] 98 } 138 return false 139 } 140 return true 141 } 142 99 143 100 144 def confirmUser = { 101 def code = params.code 102 def id = params.id 103 104 def user = SecUser.findById(id) 105 106 def generatedCode = ( user.username + user.password + "user" ).encodeAsMD5() 107 if( !user || code != generatedCode ) { 145 def token = params.code 146 147 def registrationCode = token ? RegistrationCode.findByToken(token) : null 148 if (!registrationCode) { 108 149 flash.message = "No user found with given parameters. Please make sure you have copied the URL correctly." 109 150 return 110 } 151 } 152 153 if (registrationCode.expiryDate.before(new Date())) { 154 flash.message = "Your registration should have been confirmed within " + UserRegistrationController.DAYS_BEFORE_EXPIRY + " days. This confirmation link has expired. Please register again." 155 return 156 } 157 158 def user = SecUser.findById(registrationCode.userId) 111 159 112 160 if( user.userConfirmed ) { … … 117 165 user.userConfirmed = true 118 166 user.save(flush: true) 167 168 // Remove the registrationCode 169 registrationCode.delete(); 119 170 120 171 if( user.adminConfirmed ) { … … 127 178 @Secured(['ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY']) 128 179 def confirmAdmin = { 129 def code = params.code 130 def id = params.id 131 132 def user = SecUser.findById(id) 133 134 def generatedCode = ( user.username + user.password + "admin" ).encodeAsMD5(); 135 if( !user || code != generatedCode ) { 180 181 def token = params.code 182 183 def registrationCode = token ? RegistrationCode.findByToken(token) : null 184 if (!registrationCode) { 136 185 flash.message = "No user found with specified code. Please make sure you have copied the URL correctly." 137 return; 138 } 186 return 187 } 188 189 if (registrationCode.expiryDate.before(new Date())) { 190 flash.message = "You should have approved this registration within " + UserRegistrationController.DAYS_BEFORE_EXPIRY_ADMIN + " days. This confirmation link has expired." 191 return 192 } 193 194 def user = SecUser.findById(registrationCode.userId) 139 195 140 196 if( user.adminConfirmed ) { … … 145 201 user.adminConfirmed = true 146 202 user.save(flush: true) 203 204 // Remove the registrationCode 205 registrationCode.delete(); 147 206 148 207 flash.message = "The registration of " + user.username + " is approved." … … 213 272 } 214 273 } 274 275 static final usernameValidator = { value, command -> 276 def user = SecUser.findByUsername( command.username ); 277 if( user ) { 278 if( user.enabled ) { 279 return "registerCommand.username.unique" 280 } else if( user.dateCreated.after( new Date() - DAYS_BEFORE_EXPIRY ) ) { 281 return "registerCommand.username.notyetconfirmed" 282 } else { 283 RegistrationCode.deleteByUser(user); 284 user.delete(flush:true); 285 } 286 } 287 } 288 215 289 } 216 290 … … 231 305 } 232 306 307 class RegisterCommand { 308 309 String username 310 String email 311 312 static constraints = { 313 email(blank: false, email: true) 314 username(blank: false, validator: UserRegistrationController.usernameValidator) 315 } 316 } -
trunk/grails-app/domain/dbnp/authentication/RegistrationCode.groovy
r985 r1144 19 19 */ 20 20 class RegistrationCode { 21 22 String username 21 int userId 23 22 String token = UUID.randomUUID().toString().replaceAll('-', '') 24 23 Date dateCreated 24 Date expiryDate 25 25 26 26 static mapping = { 27 27 version false 28 28 } 29 30 public static boolean deleteByUser( SecUser user ) { 31 RegistrationCode.findByUserId(user.id)*.delete(); 32 return true; 33 } 29 34 } -
trunk/grails-app/domain/dbnp/authentication/SecUser.groovy
r976 r1144 6 6 String password 7 7 String email 8 Date dateCreated 8 9 boolean enabled 9 10 boolean accountExpired -
trunk/grails-app/i18n/messages.spring-security-ui.properties
r1138 r1144 80 80 81 81 registerCommand.username.blank Username is required 82 registerCommand.username.unique The username is taken82 registerCommand.username.unique The username already exists 83 83 registerCommand.email.blank Email is required 84 84 registerCommand.email.email.invalid Please provide a valid email address … … 97 97 profileCommand.password.maxSize.exceeded Password must be between 8 and 64 characters 98 98 profileCommand.email.email.invalid Please provide a valid email address 99 100 registerCommand.username.unique The username already exists 101 registerCommand.username.notyetconfirmed This account already exists but has not yet been confirmed. If you are the owner, please check your email. 102 registerCommand.email.email.invalid Please provide a valid email address 103 registerCommand.email.blank Please provide a valid email address -
trunk/grails-app/views/common/_login_panel.gsp
r1138 r1144 29 29 </div> 30 30 <div class="left right"> 31 <g:form url="[action:'add',controller:'userRegistration']" class="clearfix">31 <g:form url="[action:'add',controller:'userRegistration']" class="clearfix registration"> 32 32 <input type="hidden" name="targetUri" value="${targetUri}" /> 33 33 <h1>Not a member yet? Sign Up!</h1> 34 <g:hasErrors bean="${command}"> 35 <g:renderErrors bean="${command}" as="list" /> 36 <g:if test="${addSendUserLink}"> 37 <a class="resend_confirmation" href="<g:createLink url="[action:'sendUserConfirmation',controller:'userRegistration', params: [username: username]]" />">Resend confirmation message</a><br /> 38 </g:if> 39 </g:hasErrors> 40 34 41 <label class="grey" for="signup">Username:</label> 35 42 <input class="field" type="text" name="username" id="username" value="${username}" size="23" /> … … 47 54 <li class="left"> </li> 48 55 <li>Hello <sec:ifLoggedIn><sec:username/></sec:ifLoggedIn> 49 56 <sec:ifNotLoggedIn>Guest</sec:ifNotLoggedIn>!</li> 50 57 <sec:ifLoggedIn> 51 58 <li class="sep">|</li> -
trunk/grails-app/views/email/_registrationConfirmationUser.gsp
r976 r1144 16 16 <p>If you can not click the link, copy this url to the browser:</p> 17 17 <p>${link}</p> 18 19 <p>You should confirm your account before <g:formatDate format="dd-MM-yyyy hh:mm" date="${expiryDate}" />, otherwise your account will not be created.</p> 20 18 21 <p>After you have confirmed your registration and the administrator has approved your account, you can login. Your password is:</p> 19 22 <p><b>${password}</b></p> -
trunk/grails-app/views/userRegistration/index.gsp
r1138 r1144 48 48 </head> 49 49 <body> 50 50 51 <div class="body" id="register"> 51 <div class="inner"> 52 <g:if test="${flash.message}"> <div class='login_message'>${flash.message}</div></g:if> 52 <div class='inner' style="margin-top: 160px;"> 53 53 54 <div class='fheader'>Please enter username and email address. </div> 55 <form action='/gscf/userRegistration/add' method='POST' id='loginForm' class='cssform' autocomplete='off'> 56 <p> 57 <label for='username'>Username</label> 58 <g:textField name="username" value="${username}" /> 59 </p> 60 <p> 61 <label for='password'>Email address</label> 62 <g:textField name="email" value="${email}" /> 63 </p> 64 <p> 65 <input type='submit' value='Register' /> 66 </p> 67 </form> 68 </div> 69 </div> 70 </body> 54 <!-- Registration in is handled in the login panel --> 55 <!-- That's why the registration form is removed here, and the data is moved down --> 56 57 <div class='fheader'>Please resolve the errors and try again..</div> 58 59 </div> 60 </div> 61 <script type='text/javascript'> 62 <!-- 63 (function(){ 64 // Open login panel 65 $("div#panel").slideDown("slow"); 66 $("#toggle a").toggle(); 67 68 })(); 69 // --> 70 </script> 71 </body> 71 72 </html> -
trunk/web-app/css/login_panel.css
r959 r1144 242 242 } 243 243 244 .registration ul { list-style-type: none; margin-left: 0; padding-left: 0; } 245 .registration ul li { margin: 3px 0; }
Note: See TracChangeset
for help on using the changeset viewer.