Project

General

Profile

« Previous | Next » 

Revision af48539c

Added by Andreas Kohlbecker about 6 years ago

ref #6867 GrantedAuthorityRevokingRegistrationUpdateLister implemented

View differences:

src/main/java/eu/etaxonomy/cdm/persistence/hibernate/GrantedAuthorityRevokingRegistrationUpdateLister.java
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.persistence.hibernate;
10

  
11
import java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.EnumSet;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Set;
17

  
18
import org.hibernate.Query;
19
import org.hibernate.event.spi.EventSource;
20
import org.hibernate.event.spi.PostUpdateEvent;
21
import org.hibernate.event.spi.PostUpdateEventListener;
22
import org.hibernate.persister.entity.EntityPersister;
23

  
24
import eu.etaxonomy.cdm.model.agent.Person;
25
import eu.etaxonomy.cdm.model.agent.Team;
26
import eu.etaxonomy.cdm.model.name.Registration;
27
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
28
import eu.etaxonomy.cdm.model.name.TaxonName;
29
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
30
import eu.etaxonomy.cdm.model.reference.Reference;
31
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
32
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
33

  
34
/**
35
 * @author a.kohlbecker
36
 * @since Dec 18, 2017
37
 *
38
 */
39
public class GrantedAuthorityRevokingRegistrationUpdateLister implements PostUpdateEventListener {
40

  
41
    private static final long serialVersionUID = -3542204523291766866L;
42

  
43
    /**
44
     *
45
     * Registrations having these states must no longer be midifiable by users having only per entity permissions on the
46
     * Registration subgraph
47
     */
48
    private static final EnumSet<RegistrationStatus> MODIFICATION_STOP_STATES = EnumSet.of(
49
            RegistrationStatus.PUBLISHED,
50
            RegistrationStatus.READY,
51
            RegistrationStatus.REJECTED
52
            );
53

  
54
    private static final EnumSet<CRUD> UPDATE_DELETE = EnumSet.of(CRUD.UPDATE, CRUD.DELETE);
55

  
56
    /**
57
     * {@inheritDoc}
58
     */
59
    @Override
60
    public void onPostUpdate(PostUpdateEvent event) {
61
        if( event.getEntity() instanceof Registration){
62
            Registration reg = (Registration)event.getEntity();
63
            if(reg.getStatus() != null && MODIFICATION_STOP_STATES.contains(reg.getStatus())){
64
                Set<CdmAuthority> deleteCandidates = collectDeleteCandidates(reg);
65
                deleteAuthorities(event.getSession(), deleteCandidates);
66
            }
67
        }
68
    }
69

  
70
    /**
71
     * Walks the entity graph of the Registration instance and collects all authorities which
72
     * could have been granted to users. Code parts in which this could have happend can be
73
     * found by searching for usage of the methods {@link eu.etaxonomy.cdm.vaadin.security.UserHelper#createAuthorityForCurrentUser(eu.etaxonomy.cdm.model.common.CdmBase, EnumSet, String)
74
     * UserHelper.createAuthorityForCurrentUser(eu.etaxonomy.cdm.model.common.CdmBase, EnumSet, String)} and {@link eu.etaxonomy.cdm.vaadin.security.UserHelper#createAuthorityForCurrentUser(Class, Integer, EnumSet, String)
75
     * UserHelper.createAuthorityForCurrentUser(Class, Integer, EnumSet, String)}
76
     * <p>
77
     * At the time of implementing this function these places are:
78
     * <ul>
79
     *  <li><code>RegistrationEditorPresenter.guaranteePerEntityCRUDPermissions(...)</code></li>
80
     *  <li><code>RegistrationWorkingsetPresenter.createNewRegistrationForName(Integer taxonNameId)</code></li>
81
     *  <li><code>TaxonNameEditorPresenter.guaranteePerEntityCRUDPermissions(...)</code></li>
82
     *  <li><code>ReferenceEditorPresenter.guaranteePerEntityCRUDPermissions(...)</code></li>
83
     *  <li><code>PersonField.commit()</code></li>
84
     *  <li><code>TeamOrPersonField.commit()</code></li>
85
     *  <li><code>SpecimenTypeDesignationWorkingsetEditorPresenter.saveBean(SpecimenTypeDesignationWorkingSetDTO dto)</code></li>
86
     * </ul>
87
     *
88
     * @param reg the Registration
89
     * @return the set of all possible CdmAuthorities that could have been granted to
90
     * individual users.
91
     */
92
    private Set<CdmAuthority> collectDeleteCandidates(Registration reg){
93
        Set<CdmAuthority> deleteCandidates = new HashSet<CdmAuthority>();
94
        // add authority for Registration
95
        deleteCandidates.add(new CdmAuthority(reg, UPDATE_DELETE));
96
        if(reg.getName() != null){
97
            addDeleteCandidates(deleteCandidates, reg.getName());
98
        }
99
        for(TypeDesignationBase td : reg.getTypeDesignations()){
100
            addDeleteCandidates(deleteCandidates, td);
101
        }
102

  
103
        return deleteCandidates;
104

  
105
    }
106

  
107
    /**
108
     * @param deleteCandidates
109
     * @param name
110
     */
111
    private void addDeleteCandidates(Set<CdmAuthority> deleteCandidates, TaxonName name) {
112
        deleteCandidates.add(new CdmAuthority(name, UPDATE_DELETE));
113
        if(name.getNomenclaturalReference() != null){
114
            addDeleteCandidates(deleteCandidates, (Reference)name.getNomenclaturalReference());
115
        }
116
    }
117

  
118

  
119
    /**
120
     * @param deleteCandidates
121
     * @param td
122
     */
123
    private void addDeleteCandidates(Set<CdmAuthority> deleteCandidates, TypeDesignationBase td) {
124
        deleteCandidates.add(new CdmAuthority(td, UPDATE_DELETE));
125
        if(td.getCitation() != null){
126
            addDeleteCandidates(deleteCandidates, td.getCitation());
127
        }
128

  
129
    }
130

  
131
    /**
132
     * @param deleteCandidates
133
     * @param nomenclaturalReference
134
     */
135
    private void addDeleteCandidates(Set<CdmAuthority> deleteCandidates,
136
            Reference reference) {
137
        deleteCandidates.add(new CdmAuthority(reference, UPDATE_DELETE));
138
        if(reference.getAuthorship() != null){
139
            deleteCandidates.add(new CdmAuthority(reference.getAuthorship(), UPDATE_DELETE));
140
            if(reference.getAuthorship() instanceof Team){
141
                List<Person> members = ((Team)reference.getAuthorship()).getTeamMembers();
142
                if(members != null){
143
                    for(Person p : members){
144
                        deleteCandidates.add(new CdmAuthority(p, UPDATE_DELETE));
145
                    }
146
                }
147
            }
148
        }
149
    }
150

  
151

  
152
    /**
153
     * @param deleteCandidates
154
     */
155
    private void deleteAuthorities(EventSource session, Set<CdmAuthority> deleteCandidates) {
156

  
157
        Collection<String> authorityStrings = new ArrayList<String>(deleteCandidates.size());
158
        deleteCandidates.forEach( dc -> authorityStrings.add(dc.toString()));
159

  
160
        String hql = "delete from GrantedAuthorityImpl as ga where ga.authority in (:authorities)";
161
        Query query = session.createQuery(hql);
162
        query.setParameterList("authorities", authorityStrings);
163
        query.executeUpdate();
164

  
165
    }
166

  
167
    @Override
168
    public boolean requiresPostCommitHanding(EntityPersister persister) {
169
        return false;
170
    }
171

  
172
}

Also available in: Unified diff