source: trunk/grails-app/controllers/PersonController.groovy @ 294

Last change on this file since 294 was 294, checked in by gav, 15 years ago

Add custom checkBoxList for personGroups to Person.
Wrap save and update in transactions, tweak role add/remove logic and use a limited role list for non-admin users.

File size: 7.2 KB
Line 
1import org.codehaus.groovy.grails.plugins.springsecurity.Secured
2
3@Secured(['ROLE_Manager','ROLE_AppAdmin'])
4class PersonController extends BaseAppAdminController {
5
6    def authenticateService
7    def filterService
8
9    // the delete, save and update actions only accept POST requests
10    static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
11
12    def index = {
13        redirect action: list, params: params
14    }
15
16    def list = {
17        params.max = Math.min( params.max ? params.max.toInteger() : 10,  100 )
18
19        if(!params.filter) {
20            return [personList: Person.list(params),
21                            personTotal: Person.count(),
22                            filterParams: params]
23        }
24
25        // filterPane:
26        return[ personList: filterService.filter( params, Person ),
27            personTotal: filterService.count( params, Person ),
28            filterParams: com.zeddware.grails.plugins.filterpane.FilterUtils.extractFilterParams(params),
29            params:params ]
30    }
31
32    def show = {
33
34        // In the case of an actionSubmit button, rewrite action name from 'index'.
35        if(params._action_Show)
36        { params.action='show' }
37
38        def person = Person.get(params.id)
39        if (!person) {
40            flash.message = "Person not found with id $params.id"
41            redirect action: list
42            return
43        }
44        List roleNames = []
45        for (role in person.authorities) {
46            roleNames << role.authority
47        }
48        roleNames.sort { n1, n2 ->
49            n1 <=> n2
50        }
51        [person: person, roleNames: roleNames]
52    }
53
54    /**
55    * Person delete action. Before removing an existing person,
56    * they should be removed from those authorities which they are involved.
57    */
58    def delete = {
59
60        def person = Person.get(params.id)
61        if (person) {
62            def authPrincipal = authenticateService.principal()
63            // Avoid self-delete.
64            if (!(authPrincipal instanceof String) && authPrincipal.username == person.loginName) {
65                flash.message = "You cannot delete yourself, please login as another manager and try again."
66                redirect(action:show,id:params.id)
67            }
68            else {
69                //first, delete this person from Persons_Authorities table.
70                Authority.findAll().each { it.removeFromPersons(person) }
71                person.isActive = false
72                person.save(flush: true)
73
74                try {
75                    person.delete(flush: true)
76                    flash.message = "Person $params.id deleted."
77                    redirect(action:list)
78                }
79                catch(org.springframework.dao.DataIntegrityViolationException e) {
80                    flash.message = "Could not delete '$person.loginName' due to database constraints, but all authorities have been removed."
81                    redirect(action:show,id:params.id)
82                }
83            }
84        }
85        else {
86            flash.message = "Person not found with id $params.id"
87        }
88    }
89
90    def edit = {
91
92        // In the case of an actionSubmit button, rewrite action name from 'index'.
93        if(params._action_Edit)
94        { params.action='edit' }
95
96        def person = Person.get(params.id)
97        if (!person) {
98            flash.message = "Person not found with id $params.id"
99            redirect action: list
100            return
101        }
102        params.message = "To allow login at least the 'ROLE_AppUser' authority must be given."
103        return buildPersonModel(person)
104    }
105
106    /**
107    * Person update action.
108    */
109    def update = {
110        Person.withTransaction { status ->
111
112            def person = Person.get(params.id)
113            if (!person) {
114                flash.message = "Person not found with id $params.id"
115                redirect action: edit, id: params.id
116                return
117            }
118
119            long version = params.version.toLong()
120            if (person.version > version) {
121                person.errors.rejectValue 'version', "person.optimistic.locking.failure",
122                    "Another user has updated this Person while you were editing."
123                render view: 'edit', model: buildPersonModel(person)
124                return
125            }
126
127            person.properties = params
128            person.setPersonGroupsFromCheckBoxList(params.personGroups)
129
130            if(params.pass == "") {
131                person.pass = "InsertNothingToClearValidation"
132            }
133            else {
134                if (person.validate()) {
135                    person.password = authenticateService.encodePassword(params.pass)
136                }
137            }
138
139            if (!person.hasErrors() && person.save(flush: true)) {
140                addRemoveRoles(person)
141                flash.message = "Person '$params.id - $params.loginName' updated."
142                redirect action: show, id: person.id
143            }
144            else {
145                render view: 'edit', model: buildPersonModel(person)
146            }
147
148        } //end withTransaction
149    } // update()
150
151    def create = {
152        params.message = "To allow login at least the 'ROLE_AppUser' authority must be given."
153        [person: new Person(params), authorityList: getLimitedAuthorityList()]
154    }
155
156    /**
157    * Person save action.
158    */
159    def save = {
160        Person.withTransaction { status ->
161
162            def person = new Person()
163            person.properties = params
164            person.password = authenticateService.encodePassword(params.pass)
165            person.setPersonGroupsFromCheckBoxList(params.personGroups)
166            if (person.save(flush: true)) {
167                addRemoveRoles(person)
168                redirect action: show, id: person.id
169            }
170            else {
171                render view: 'create', model: [person: person, authorityList: getLimitedAuthorityList()]
172            }
173
174        } //end withTransaction
175    }
176
177    private void addRemoveRoles(person) {
178        for (key in params.keySet()) {
179            if(key.startsWith("ROLE"))
180                Authority.findByAuthority(key).addToPersons(person)
181            else if(key.startsWith("_ROLE"))
182                Authority.findByAuthority(key.substring(1)).removeFromPersons(person)
183        }
184    }
185
186    private Map buildPersonModel(person) {
187
188        List roles = getLimitedAuthorityList()
189        roles.sort { r1, r2 ->
190            r1.authority <=> r2.authority
191        }
192        Set userRoleNames = []
193        for (role in person.authorities) {
194            userRoleNames << role.authority
195        }
196        LinkedHashMap<Authority, Boolean> roleMap = [:]
197        for (role in roles) {
198            roleMap[(role)] = userRoleNames.contains(role.authority)
199        }
200
201        return [person: person, roleMap: roleMap]
202    }
203
204    /**
205    * Get the full authorityList if current user is an App Admin else leave that authority off the list.
206    */
207    def getLimitedAuthorityList = {
208        def authorityList = []
209        if(authenticateService.ifAnyGranted('ROLE_AppAdmin'))
210            authorityList = Authority.list().sort { p1, p2 -> p1.authority.compareToIgnoreCase(p2.authority) }
211        else
212            authorityList = Authority.withCriteria { gt("id", 1L) }.sort { p1, p2 -> p1.authority.compareToIgnoreCase(p2.authority) }
213
214        return authorityList
215    }
216}
Note: See TracBrowser for help on using the repository browser.