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

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

Full authorisation review.
Add manager role to BaseController.
Remove inventory manager role from CostCode controller as per ticket #77.
Remove inventory manager role from InventoryGroup controller CUD actions.
Add all manager roles to Address and Contact controllers.
Add production and task manager roles to ProductionReference controller.

File size: 8.6 KB
RevLine 
[62]1import org.codehaus.groovy.grails.plugins.springsecurity.Secured
[440]2import org.codehaus.groovy.grails.commons.ConfigurationHolder
[58]3
[628]4@Secured(['ROLE_AppAdmin', 'ROLE_Manager'])
[97]5class PersonController extends BaseAppAdminController {
[58]6
[440]7    def filterService
8    def personCsvService
[147]9    def authenticateService
[58]10
[150]11    // the delete, save and update actions only accept POST requests
12    static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
[58]13
[150]14    def index = {
15        redirect action: list, params: params
16    }
[58]17
[440]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
[147]53    def list = {
54        params.max = Math.min( params.max ? params.max.toInteger() : 10,  100 )
[58]55
[250]56        if(!params.filter) {
57            return [personList: Person.list(params),
58                            personTotal: Person.count(),
59                            filterParams: params]
60        }
[147]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
[150]69    def show = {
[147]70
71        // In the case of an actionSubmit button, rewrite action name from 'index'.
72        if(params._action_Show)
[375]73            params.action='show'
[147]74
[150]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        }
[295]81        def authorityList = person.authorities.sort { p1, p2 -> p1.id <=> p2.id }
82        [person: person, authorityList: authorityList]
[150]83    }
[58]84
[150]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 = {
[58]90
[150]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."
[147]97                redirect(action:show,id:params.id)
[150]98            }
99            else {
100                //first, delete this person from Persons_Authorities table.
101                Authority.findAll().each { it.removeFromPersons(person) }
[147]102                person.isActive = false
103                person.save(flush: true)
104
[97]105                try {
[147]106                    person.delete(flush: true)
[91]107                    flash.message = "Person $params.id deleted."
[97]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                }
[150]114            }
115        }
116        else {
117            flash.message = "Person not found with id $params.id"
118        }
119    }
[58]120
[150]121    def edit = {
[58]122
[147]123        // In the case of an actionSubmit button, rewrite action name from 'index'.
124        if(params._action_Edit)
[375]125            params.action='edit'
[147]126
[150]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    }
[58]136
[150]137    /**
[294]138    * Person update action.
139    */
[150]140    def update = {
[294]141        Person.withTransaction { status ->
[58]142
[294]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            }
[58]149
[294]150            long version = params.version.toLong()
151            if (person.version > version) {
[403]152                person.errors.rejectValue 'version', "default.optimistic.locking.failure"
[294]153                render view: 'edit', model: buildPersonModel(person)
154                return
155            }
[58]156
[294]157            person.properties = params
158            person.setPersonGroupsFromCheckBoxList(params.personGroups)
[73]159
[294]160            if(params.pass == "") {
161                person.pass = "InsertNothingToClearValidation"
[73]162            }
[294]163            else {
164                if (person.validate()) {
165                    person.password = authenticateService.encodePassword(params.pass)
166                }
167            }
[73]168
[294]169            if (!person.hasErrors() && person.save(flush: true)) {
[295]170                addRemoveAuthorities(person)
[294]171                flash.message = "Person '$params.id - $params.loginName' updated."
172                redirect action: show, id: person.id
173            }
174            else {
175                render view: 'edit', model: buildPersonModel(person)
176            }
[73]177
[294]178        } //end withTransaction
179    } // update()
[58]180
[150]181    def create = {
182        params.message = "To allow login at least the 'ROLE_AppUser' authority must be given."
[294]183        [person: new Person(params), authorityList: getLimitedAuthorityList()]
[150]184    }
[58]185
[150]186    /**
[294]187    * Person save action.
188    */
[150]189    def save = {
[294]190        Person.withTransaction { status ->
[58]191
[294]192            def person = new Person()
193            person.properties = params
194            person.password = authenticateService.encodePassword(params.pass)
195            person.setPersonGroupsFromCheckBoxList(params.personGroups)
196            if (person.save(flush: true)) {
[295]197                addRemoveAuthorities(person)
[294]198                redirect action: show, id: person.id
199            }
200            else {
201                render view: 'create', model: [person: person, authorityList: getLimitedAuthorityList()]
202            }
203
204        } //end withTransaction
[150]205    }
[58]206
[295]207    /**
208    * Add or remove authorities from person as indicated in params.
209    */
210    private void addRemoveAuthorities(person) {
211        def authMap = [:]
212
213        // Build authMap from params.
[294]214        for (key in params.keySet()) {
[295]215            if(key.startsWith("ROLE")) {
216                authMap.(key.toString()) = "add"
217            }
218            else if(key.startsWith("_ROLE")) {
219                if( !authMap.(key.substring(1)) ) authMap.(key.substring(1)) = "remove"
220            }
[150]221        }
[295]222
223        // Add or remove authorities.
224        for(a in authMap) {
225            if(a.value == "add")
226                Authority.findByAuthority(a.key.toString()).addToPersons(person)
227            else
228                Authority.findByAuthority(a.key.toString()).removeFromPersons(person)
229        }
[150]230    }
[58]231
[150]232    private Map buildPersonModel(person) {
[58]233
[294]234        List roles = getLimitedAuthorityList()
[150]235        Set userRoleNames = []
236        for (role in person.authorities) {
237            userRoleNames << role.authority
238        }
239        LinkedHashMap<Authority, Boolean> roleMap = [:]
240        for (role in roles) {
241            roleMap[(role)] = userRoleNames.contains(role.authority)
242        }
[58]243
[150]244        return [person: person, roleMap: roleMap]
245    }
[294]246
247    /**
248    * Get the full authorityList if current user is an App Admin else leave that authority off the list.
249    */
[295]250    private List getLimitedAuthorityList() {
[294]251        def authorityList = []
252        if(authenticateService.ifAnyGranted('ROLE_AppAdmin'))
[295]253            authorityList = Authority.list().sort { p1, p2 -> p1.id <=> p2.id }
[294]254        else
[295]255            authorityList = Authority.withCriteria { gt("id", 1L) }.sort { p1, p2 -> p1.id <=> p2.id }
[294]256
257        return authorityList
258    }
[295]259} // end class
Note: See TracBrowser for help on using the repository browser.