source: trunk/grails-app/controllers/dbnp/authentication/UserController.groovy @ 2084

Last change on this file since 2084 was 2084, checked in by work@…, 10 years ago

shibboleth changes - in development...

  • Property svn:keywords set to Rev Author Date
File size: 6.6 KB
Line 
1/* Copyright 2009-2010 the original author or authors.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *      http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15package dbnp.authentication
16
17import grails.converters.JSON
18import grails.plugins.springsecurity.Secured
19import org.springframework.dao.DataIntegrityViolationException
20
21/**
22 * @author <a href='mailto:burt@burtbeckwith.com'>Burt Beckwith</a>
23 */
24@Secured(['ROLE_ADMIN'])
25class UserController {
26
27        def userCache
28        def springSecurityService
29
30        static defaultAction = 'search'
31
32        def create = {
33                if (!session.gscfUser.shibbolethUser) {
34                        def user = new SecUser(params)
35                        [user: user, authorityList: sortedRoles()]
36                } else {
37                        response.sendError(404)
38                }
39        }
40
41        def save = {
42                def user = new SecUser(params)
43                if (params.password) {
44                        user.password = springSecurityService.encodePassword(params.password, params.username)
45                }
46                if (!user.save(flush: true)) {
47                        // Reset encoded password
48                        user.password = params.password
49                        render view: 'create', model: [user: user, authorityList: sortedRoles()]
50                        return
51                }
52
53                addRoles(user)
54                flash.message = "${message(code: 'default.created.message', args: [message(code: 'user.label', default: 'User'), user.id])}"
55                redirect action: edit, id: user.id
56        }
57
58        def edit = {
59                def user = findById()
60
61                if (!user) return
62
63                return buildUserModel(user)
64        }
65
66        def update = {
67                def user = findById()
68                if (!user) return
69
70                if (!versionCheck('user.label', 'User', user, [user: user])) {
71                        return
72                }
73               
74                def oldPassword = user.password
75                user.properties = params
76                if (params.password && !params.password.equals(oldPassword)) {
77                        user.password = springSecurityService.encodePassword(params.password, params.username)
78                }
79
80                if (!user.save()) {
81                        render view: 'edit', model: buildUserModel(user)
82                        return
83                }
84
85                SecUserSecRole.removeAll user
86                addRoles user
87               
88                userCache.removeUserFromCache user.username
89
90                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'user.label', default: 'User'), user.id])}"
91                redirect action: edit, id: user.id
92        }
93
94        def delete = {
95                def user = findById()
96                if (!user) return
97
98                try {
99                        SecUserSecRole.removeAll user
100                        user.delete flush: true
101
102                        userCache.removeUserFromCache user.username
103                       
104                        flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
105                        redirect action: search
106                }
107                catch (DataIntegrityViolationException e) {
108                        flash.userError = "${message(code: 'default.not.deleted.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
109                        redirect action: edit, id: params.id
110                }
111        }
112
113        def search = {
114                [enabled: 0, accountExpired: 0, accountLocked: 0, passwordExpired: 0]
115        }
116
117        def userSearch = {
118
119                boolean useOffset = params.containsKey('offset')
120                params.max = params.max ?: 10
121                params.offset = params.offset ?: 0
122
123                def hql = new StringBuilder('FROM SecUser u WHERE 1=1 ')
124                def queryParams = [:]
125
126                for (name in ['username']) {
127                        if (params[name]) {
128                                hql.append " AND LOWER(u.$name) LIKE :$name"
129                                queryParams[name] = params[name].toLowerCase() + '%'
130                        }
131                }
132
133                for (name in ['enabled', 'accountExpired', 'accountLocked', 'passwordExpired']) {
134                        int value = params.int(name)
135                        if (value) {
136                                hql.append " AND u.$name=:$name"
137                                queryParams[name] = value == 1
138                        }
139                }
140
141                int totalCount = SecUser.executeQuery("SELECT COUNT(DISTINCT u) $hql", queryParams)[0]
142
143                int max = params.int('max')
144                int offset = params.int('offset')
145
146                String orderBy = ''
147                if (params.sort) {
148                        orderBy = " ORDER BY u.$params.sort ${params.order ?: 'ASC'}"
149                }
150
151                def results = SecUser.executeQuery(
152                                "SELECT DISTINCT u $hql $orderBy",
153                                queryParams, [max: max, offset: offset])
154                def model = [results: results, totalCount: totalCount, searched: true]
155
156                // add query params to model for paging
157                for (name in ['username', 'enabled', 'accountExpired', 'accountLocked',
158                              'passwordExpired', 'sort', 'order']) {
159                        model[name] = params[name]
160                }
161
162                render view: 'search', model: model
163        }
164
165        /**
166         * Ajax call used by autocomplete textfield.
167         */
168        def ajaxUserSearch = {
169
170                def jsonData = []
171
172                if (params.term?.length() > 2) {
173                        String username = params.term
174
175                        setIfMissing 'max', 10, 100
176
177                        def results = SecUser.executeQuery(
178                                        "SELECT DISTINCT u.username " +
179                                        "FROM SecUser u " +
180                                        "WHERE LOWER(u.username) LIKE :name " +
181                                        "ORDER BY u.username",
182                                        [name: "${username.toLowerCase()}%"],
183                                        [max: params.max])
184
185                        for (result in results) {
186                                jsonData << [value: result]
187                        }
188                }
189
190                render text: jsonData as JSON, contentType: 'application/json'
191        }
192
193        protected void addRoles(user) {
194                for (String key in params.keySet()) {
195                        if (key.contains('ROLE') && 'on' == params.get(key)) {
196                                SecUserSecRole.create user, SecRole.findByAuthority(key), true
197                        }
198                }
199        }
200
201        protected Map buildUserModel(user) {
202
203                List roles = sortedRoles()
204                Set userRoleNames = user.authorities*.authority
205                def granted = [:]
206                def notGranted = [:]
207                for (role in roles) {
208                        if (userRoleNames.contains(role.authority)) {
209                                granted[(role)] = userRoleNames.contains(role.authority)
210                        }
211                        else {
212                                notGranted[(role)] = userRoleNames.contains(role.authority)
213                        }
214                }
215
216                return [user: user, roleMap: granted + notGranted]
217        }
218
219        protected findById() {
220                if(!params.id) {
221                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
222                        redirect action: search
223                }
224
225                def user = SecUser.get(params.id)
226               
227                if (!user) {
228                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
229                        redirect action: search
230                }
231
232                user
233        }
234
235        protected List sortedRoles() {
236                SecRole.list().sort { it.authority }
237        }
238
239        protected boolean versionCheck(String messageCode, String messageCodeDefault, instance, model) {
240                if (params.version) {
241                        def version = params.version.toLong()
242                        if (instance.version > version) {
243                                instance.errors.rejectValue('version', 'default.optimistic.locking.failure',
244                                                [message(code: messageCode, default: messageCodeDefault)] as Object[],
245                                                "Another user has updated this instance while you were editing")
246                                render view: 'edit', model: model
247                                return false
248                        }
249                }
250                true
251        }
252}
Note: See TracBrowser for help on using the repository browser.