source: trunk/grails-app/controllers/dbnp/authentication/UserRegistrationController.groovy @ 976

Last change on this file since 976 was 976, checked in by robert@…, 11 years ago

Authentication and authorization for studies is added, according to ticket 118

File size: 5.8 KB
Line 
1/**
2 * RegisterController Controler
3 *
4 * This controller handles user subscription
5 *
6 * @author      robert@isdat.nl (Robert Horlings)
7 * @since       20101016
8 * @package     dbnp.authentication
9 *
10 * Revision information:
11 * $Rev$
12 * $Author$
13 * $Date$
14 */
15package dbnp.authentication
16import grails.plugins.springsecurity.Secured
17
18class UserRegistrationController {
19    def springSecurityService
20   
21    /**
22     * Shows a simple registration form
23     */
24    def index = {
25
26    }
27
28    /**
29     * Registers a new user. Also sends an e-mail to the user and to the administrators
30     * for confirmation
31     */
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        }
45
46        // Generate a random password
47        def password = this.generatePassword(8)
48
49        def user = new SecUser(
50           username: params.username,
51           email: params.email,
52           password: springSecurityService.encodePassword(password, params.username),
53           userConfirmed: true, adminConfirmed: true)
54       
55        // Redirect user if save fails
56        if( !user.save(failOnError: true) ) {
57            render(view: "index", model: [username: params.username, email: params.email])
58            return
59        }
60
61        // Clear the flash message so the user does not see old messages
62        flash.message = ""
63
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 )
71
72        // Send an email to the user
73        try {
74            sendMail {
75                to      params.email
76                subject "Registration at GSCF"
77                html    g.render(template:'/email/registrationConfirmationUser', model:[username: user.username, password: password, link: userLink])
78            }
79        } catch(Exception e) {
80            log.error "Problem sending email $e.message", e
81            flash.message = 'Email could not be sent'
82        }
83
84        // Send an email to the administrators
85        try {
86            sendMail {
87                to      "gscfproject@gmail.com"
88                subject "New user (" + user.username + ") at GSCF"
89                html    g.render(template:"/email/registrationConfirmationAdmin", model:[username: user.username, email: user.email, link: adminLink])
90            }
91        } catch(Exception e) {
92            log.error "Problem sending email $e.message", e
93            flash.message = "Email could not be sent to administrators"
94        }
95
96        // Give the user a nice welcome page
97        [username: user.username, password: password]
98    }
99
100    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 ) {
108            flash.message = "No user found with given parameters. Please make sure you have copied the URL correctly."
109            return
110        }
111
112        if( user.userConfirmed ) {
113            flash.message = "This registration has already been confirmed."
114            return
115        }
116
117        user.userConfirmed = true
118        user.save(flush: true)
119
120        if( user.adminConfirmed ) {
121            flash.message = "Your registration has been confirmed. You can now login."
122        } else {
123            flash.message = "Your registration has been confirmed. An administrator has to approve your registration before you can use it."
124        }
125    }
126
127    @Secured(['ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY'])
128    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 ) {
136            flash.message = "No user found with specified code. Please make sure you have copied the URL correctly."
137            return;
138        }
139
140        if( user.adminConfirmed ) {
141            flash.message = "This user has already been approved. This might be done by another administrator"
142            return
143        }
144
145        user.adminConfirmed = true
146        user.save(flush: true)
147
148        flash.message = "The registration of " + user.username + " is approved."
149    }
150
151    private String generatePassword( int length ) {
152        String validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-!@#%^&*()/\\;:"
153        int maxIndex = validChars.length()
154       
155        java.util.Random rnd = new java.util.Random(System.currentTimeMillis()*(new java.util.Random().nextInt()))
156        String resultID = ""
157       
158        for ( i in 0..length ) {
159            int rndPos = Math.abs(rnd.nextInt() % maxIndex);
160            resultID += validChars.charAt(rndPos)
161        }
162
163        return resultID
164    }
165}
Note: See TracBrowser for help on using the repository browser.