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

Last change on this file since 673 was 633, checked in by gav, 14 years ago

Domain change: Add PurchasingGroup?.
Logic and views to suite.

File size: 8.8 KB
Line 
1import org.codehaus.groovy.grails.plugins.springsecurity.Secured
2import org.codehaus.groovy.grails.commons.ConfigurationHolder
3
4@Secured(['ROLE_AppAdmin', 'ROLE_Manager'])
5class PersonController extends BaseAppAdminController {
6
7    def filterService
8    def personCsvService
9    def authenticateService
10
11    // the delete, save and update actions only accept POST requests
12    static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
13
14    def index = {
15        redirect action: list, params: params
16    }
17
18    /**
19    * Disaply the import view.
20    */
21    def importPersons = {
22    }
23
24    /**
25    * Handle the import save.
26    */
27    def importPersonsSave = {
28        def result = personCsvService.importPersons(request)
29
30        if(!result.error) {
31            response.contentType = ConfigurationHolder.config.grails.mime.types["text"]
32            response.setHeader("Content-disposition", "attachment; filename=LoginNamesAndPasswords.txt")
33            render result.loginNamesAndPasswords
34            return
35        }
36
37        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
38        redirect(action: importPersons)
39    }
40
41    /**
42    * Export a csv template.
43    * NOTE: IE has a 'validating' bug in dev mode that causes the export to take a long time!
44    * This does not appear to be a problem once deployed to Tomcat.
45    */
46    def exportPersonsTemplate = {
47        response.contentType = ConfigurationHolder.config.grails.mime.types["csv"]
48        response.setHeader("Content-disposition", "attachment; filename=personsTemplate.csv")
49        def s = personCsvService.buildPersonsTemplate()
50        render s
51    }
52
53    def list = {
54        params.max = Math.min( params.max ? params.max.toInteger() : 10,  100 )
55
56        if(!params.filter) {
57            return [personList: Person.list(params),
58                            personTotal: Person.count(),
59                            filterParams: params]
60        }
61
62        // filterPane:
63        return[ personList: filterService.filter( params, Person ),
64            personTotal: filterService.count( params, Person ),
65            filterParams: com.zeddware.grails.plugins.filterpane.FilterUtils.extractFilterParams(params),
66            params:params ]
67    }
68
69    def show = {
70
71        // In the case of an actionSubmit button, rewrite action name from 'index'.
72        if(params._action_Show)
73            params.action='show'
74
75        def person = Person.get(params.id)
76        if (!person) {
77            flash.message = "Person not found with id $params.id"
78            redirect action: list
79            return
80        }
81        def authorityList = person.authorities.sort { p1, p2 -> p1.id <=> p2.id }
82        [person: person, authorityList: authorityList]
83    }
84
85    /**
86    * Person delete action. Before removing an existing person,
87    * they should be removed from those authorities which they are involved.
88    */
89    def delete = {
90
91        def person = Person.get(params.id)
92        if (person) {
93            def authPrincipal = authenticateService.principal()
94            // Avoid self-delete.
95            if (!(authPrincipal instanceof String) && authPrincipal.username == person.loginName) {
96                flash.message = "You cannot delete yourself, please login as another manager and try again."
97                redirect(action:show,id:params.id)
98            }
99            else {
100                //first, delete this person from Persons_Authorities table.
101                Authority.findAll().each { it.removeFromPersons(person) }
102                person.isActive = false
103                person.save(flush: true)
104
105                try {
106                    person.delete(flush: true)
107                    flash.message = "Person $params.id deleted."
108                    redirect(action:list)
109                }
110                catch(org.springframework.dao.DataIntegrityViolationException e) {
111                    flash.message = "Could not delete '$person.loginName' due to database constraints, but all authorities have been removed."
112                    redirect(action:show,id:params.id)
113                }
114            }
115        }
116        else {
117            flash.message = "Person not found with id $params.id"
118        }
119    }
120
121    def edit = {
122
123        // In the case of an actionSubmit button, rewrite action name from 'index'.
124        if(params._action_Edit)
125            params.action='edit'
126
127        def person = Person.get(params.id)
128        if (!person) {
129            flash.message = "Person not found with id $params.id"
130            redirect action: list
131            return
132        }
133        params.message = "To allow login at least the 'ROLE_AppUser' authority must be given."
134        return buildPersonModel(person)
135    }
136
137    /**
138    * Person update action.
139    */
140    def update = {
141        Person.withTransaction { status ->
142
143            def person = Person.get(params.id)
144            if (!person) {
145                flash.message = "Person not found with id $params.id"
146                redirect action: edit, id: params.id
147                return
148            }
149
150            long version = params.version.toLong()
151            if (person.version > version) {
152                person.errors.rejectValue 'version', "default.optimistic.locking.failure"
153                render view: 'edit', model: buildPersonModel(person)
154                return
155            }
156
157            person.properties = params
158            person.setPersonGroupsFromCheckBoxList(params.personGroups)
159            person.setPurchasingGroupsFromCheckBoxList(params.purchasingGroups)
160
161            if(params.pass == "") {
162                person.pass = "InsertNothingToClearValidation"
163            }
164            else {
165                if (person.validate()) {
166                    person.password = authenticateService.encodePassword(params.pass)
167                }
168            }
169
170            if (!person.hasErrors() && person.save(flush: true)) {
171                addRemoveAuthorities(person)
172                flash.message = "Person '$params.id - $params.loginName' updated."
173                redirect action: show, id: person.id
174            }
175            else {
176                render view: 'edit', model: buildPersonModel(person)
177            }
178
179        } //end withTransaction
180    } // update()
181
182    def create = {
183        params.message = "To allow login at least the 'ROLE_AppUser' authority must be given."
184        [person: new Person(params), authorityList: getLimitedAuthorityList()]
185    }
186
187    /**
188    * Person save action.
189    */
190    def save = {
191        Person.withTransaction { status ->
192
193            def person = new Person()
194            person.properties = params
195            person.password = authenticateService.encodePassword(params.pass)
196            person.setPersonGroupsFromCheckBoxList(params.personGroups)
197            person.setPurchasingGroupsFromCheckBoxList(params.purchasingGroups)
198            if (person.save(flush: true)) {
199                addRemoveAuthorities(person)
200                redirect action: show, id: person.id
201            }
202            else {
203                render view: 'create', model: [person: person, authorityList: getLimitedAuthorityList()]
204            }
205
206        } //end withTransaction
207    }
208
209    /**
210    * Add or remove authorities from person as indicated in params.
211    */
212    private void addRemoveAuthorities(person) {
213        def authMap = [:]
214
215        // Build authMap from params.
216        for (key in params.keySet()) {
217            if(key.startsWith("ROLE")) {
218                authMap.(key.toString()) = "add"
219            }
220            else if(key.startsWith("_ROLE")) {
221                if( !authMap.(key.substring(1)) ) authMap.(key.substring(1)) = "remove"
222            }
223        }
224
225        // Add or remove authorities.
226        for(a in authMap) {
227            if(a.value == "add")
228                Authority.findByAuthority(a.key.toString()).addToPersons(person)
229            else
230                Authority.findByAuthority(a.key.toString()).removeFromPersons(person)
231        }
232    }
233
234    private Map buildPersonModel(person) {
235
236        List roles = getLimitedAuthorityList()
237        Set userRoleNames = []
238        for (role in person.authorities) {
239            userRoleNames << role.authority
240        }
241        LinkedHashMap<Authority, Boolean> roleMap = [:]
242        for (role in roles) {
243            roleMap[(role)] = userRoleNames.contains(role.authority)
244        }
245
246        return [person: person, roleMap: roleMap]
247    }
248
249    /**
250    * Get the full authorityList if current user is an App Admin else leave that authority off the list.
251    */
252    private List getLimitedAuthorityList() {
253        def authorityList = []
254        if(authenticateService.ifAnyGranted('ROLE_AppAdmin'))
255            authorityList = Authority.list().sort { p1, p2 -> p1.id <=> p2.id }
256        else
257            authorityList = Authority.withCriteria { gt("id", 1L) }.sort { p1, p2 -> p1.id <=> p2.id }
258
259        return authorityList
260    }
261} // end class
Note: See TracBrowser for help on using the repository browser.