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

Last change on this file since 1430 was 1430, checked in by work@…, 10 years ago
  • set keyword expansion
  • Property svn:keywords set to Rev Author Date
File size: 6.5 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                def user = new SecUser(params)
34                [user: user, authorityList: sortedRoles()]
35        }
36
37        def save = {
38                def user = new SecUser(params)
39                if (params.password) {
40                        user.password = springSecurityService.encodePassword(params.password, params.username)
41                }
42                if (!user.save(flush: true)) {
43                        // Reset encoded password
44                        user.password = params.password
45                        render view: 'create', model: [user: user, authorityList: sortedRoles()]
46                        return
47                }
48
49                addRoles(user)
50                flash.message = "${message(code: 'default.created.message', args: [message(code: 'user.label', default: 'User'), user.id])}"
51                redirect action: edit, id: user.id
52        }
53
54        def edit = {
55                def user = findById()
56
57                if (!user) return
58
59                return buildUserModel(user)
60        }
61
62        def update = {
63                def user = findById()
64                if (!user) return
65
66                if (!versionCheck('user.label', 'User', user, [user: user])) {
67                        return
68                }
69               
70                def oldPassword = user.password
71                user.properties = params
72                if (params.password && !params.password.equals(oldPassword)) {
73                        user.password = springSecurityService.encodePassword(params.password, params.username)
74                }
75
76                if (!user.save()) {
77                        render view: 'edit', model: buildUserModel(user)
78                        return
79                }
80
81                SecUserSecRole.removeAll user
82                addRoles user
83               
84                userCache.removeUserFromCache user.username
85
86                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'user.label', default: 'User'), user.id])}"
87                redirect action: edit, id: user.id
88        }
89
90        def delete = {
91                def user = findById()
92                if (!user) return
93
94                try {
95                        SecUserSecRole.removeAll user
96                        user.delete flush: true
97
98                        userCache.removeUserFromCache user.username
99                       
100                        flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
101                        redirect action: search
102                }
103                catch (DataIntegrityViolationException e) {
104                        flash.userError = "${message(code: 'default.not.deleted.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
105                        redirect action: edit, id: params.id
106                }
107        }
108
109        def search = {
110                [enabled: 0, accountExpired: 0, accountLocked: 0, passwordExpired: 0]
111        }
112
113        def userSearch = {
114
115                boolean useOffset = params.containsKey('offset')
116                params.max = params.max ?: 10
117                params.offset = params.offset ?: 0
118
119                def hql = new StringBuilder('FROM SecUser u WHERE 1=1 ')
120                def queryParams = [:]
121
122                for (name in ['username']) {
123                        if (params[name]) {
124                                hql.append " AND LOWER(u.$name) LIKE :$name"
125                                queryParams[name] = params[name].toLowerCase() + '%'
126                        }
127                }
128
129                for (name in ['enabled', 'accountExpired', 'accountLocked', 'passwordExpired']) {
130                        int value = params.int(name)
131                        if (value) {
132                                hql.append " AND u.$name=:$name"
133                                queryParams[name] = value == 1
134                        }
135                }
136
137                int totalCount = SecUser.executeQuery("SELECT COUNT(DISTINCT u) $hql", queryParams)[0]
138
139                int max = params.int('max')
140                int offset = params.int('offset')
141
142                String orderBy = ''
143                if (params.sort) {
144                        orderBy = " ORDER BY u.$params.sort ${params.order ?: 'ASC'}"
145                }
146
147                def results = SecUser.executeQuery(
148                                "SELECT DISTINCT u $hql $orderBy",
149                                queryParams, [max: max, offset: offset])
150                def model = [results: results, totalCount: totalCount, searched: true]
151
152                // add query params to model for paging
153                for (name in ['username', 'enabled', 'accountExpired', 'accountLocked',
154                              'passwordExpired', 'sort', 'order']) {
155                        model[name] = params[name]
156                }
157
158                render view: 'search', model: model
159        }
160
161        /**
162         * Ajax call used by autocomplete textfield.
163         */
164        def ajaxUserSearch = {
165
166                def jsonData = []
167
168                if (params.term?.length() > 2) {
169                        String username = params.term
170
171                        setIfMissing 'max', 10, 100
172
173                        def results = SecUser.executeQuery(
174                                        "SELECT DISTINCT u.username " +
175                                        "FROM SecUser u " +
176                                        "WHERE LOWER(u.username) LIKE :name " +
177                                        "ORDER BY u.username",
178                                        [name: "${username.toLowerCase()}%"],
179                                        [max: params.max])
180
181                        for (result in results) {
182                                jsonData << [value: result]
183                        }
184                }
185
186                render text: jsonData as JSON, contentType: 'text/plain'
187        }
188
189        protected void addRoles(user) {
190                for (String key in params.keySet()) {
191                        if (key.contains('ROLE') && 'on' == params.get(key)) {
192                                SecUserSecRole.create user, SecRole.findByAuthority(key), true
193                        }
194                }
195        }
196
197        protected Map buildUserModel(user) {
198
199                List roles = sortedRoles()
200                Set userRoleNames = user.authorities*.authority
201                def granted = [:]
202                def notGranted = [:]
203                for (role in roles) {
204                        if (userRoleNames.contains(role.authority)) {
205                                granted[(role)] = userRoleNames.contains(role.authority)
206                        }
207                        else {
208                                notGranted[(role)] = userRoleNames.contains(role.authority)
209                        }
210                }
211
212                return [user: user, roleMap: granted + notGranted]
213        }
214
215        protected findById() {
216                if(!params.id) {
217                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
218                        redirect action: search
219                }
220
221                def user = SecUser.get(params.id)
222               
223                if (!user) {
224                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
225                        redirect action: search
226                }
227
228                user
229        }
230
231        protected List sortedRoles() {
232                SecRole.list().sort { it.authority }
233        }
234
235        protected boolean versionCheck(String messageCode, String messageCodeDefault, instance, model) {
236                if (params.version) {
237                        def version = params.version.toLong()
238                        if (instance.version > version) {
239                                instance.errors.rejectValue('version', 'default.optimistic.locking.failure',
240                                                [message(code: messageCode, default: messageCodeDefault)] as Object[],
241                                                "Another user has updated this instance while you were editing")
242                                render view: 'edit', model: model
243                                return false
244                        }
245                }
246                true
247        }
248}
Note: See TracBrowser for help on using the repository browser.