001    /**
002     * 
003     * $Revision: 15202 $ $Date: 2009-05-15 17:00:44 +0200 (Fri, 15 May 2009) $
004     *
005     * This file is part of ***  M y C o R e  ***
006     * See http://www.mycore.de/ for details.
007     *
008     * This program is free software; you can use it, redistribute it
009     * and / or modify it under the terms of the GNU General Public License
010     * (GPL) as published by the Free Software Foundation; either version 2
011     * of the License or (at your option) any later version.
012     *
013     * This program is distributed in the hope that it will be useful, but
014     * WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program, in a file called gpl.txt or license.txt.
020     * If not, write to the Free Software Foundation Inc.,
021     * 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
022     */
023    
024    // package
025    package org.mycore.access;
026    
027    import java.util.Collection;
028    
029    import org.apache.log4j.Logger;
030    import org.jdom.Element;
031    import org.mycore.common.MCRConfiguration;
032    import org.mycore.common.events.MCREvent;
033    import org.mycore.common.events.MCREventHandlerBase;
034    import org.mycore.common.xml.MCRXMLHelper;
035    import org.mycore.datamodel.metadata.MCRBase;
036    import org.mycore.datamodel.metadata.MCRDerivate;
037    import org.mycore.datamodel.metadata.MCRObject;
038    
039    /**
040     * This class holds all EventHandler methods to manage the access part of the
041     * simple workflow.
042     * 
043     * @author Jens Kupferschmidt
044     * @version $Revision: 15202 $ $Date: 2009-05-15 17:00:44 +0200 (Fri, 15 May 2009) $
045     */
046    public class MCRAccessEventHandler extends MCREventHandlerBase {
047    
048        // the logger
049        private static Logger LOGGER = Logger.getLogger(MCRAccessEventHandler.class);
050    
051        private static MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
052    
053        private static String storedrules = MCRConfiguration.instance().getString("MCR.Access.StorePermissions", "read,write,delete");
054    
055        // get the standard read rule from config or it's the true rule
056        private static String strReadRule = MCRConfiguration.instance().getString("MCR.Access.Rule.STANDARD-READ-RULE",
057                "<condition format=\"xml\"><boolean operator=\"true\" /></condition>");
058    
059        private static Element readrule = (Element) MCRXMLHelper.parseXML(strReadRule, false).getRootElement().detach();
060    
061        // get the standard edit rule from config or it's the true rule
062        private static String strEditRule = MCRConfiguration.instance().getString("MCR.Access.Rule.STANDARD-EDIT-RULE",
063                "<condition format=\"xml\"><boolean operator=\"true\" /></condition>");
064    
065        private static Element editrule = (Element) MCRXMLHelper.parseXML(strEditRule, false).getRootElement().detach();
066    
067        /**
068         * This method will be used to create the access rules for SWF for a
069         * MCRObject.
070         * 
071         * @param evt
072         *            the event that occured
073         * @param obj
074         *            the MCRObject that caused the event
075         */
076        protected void handleObjectCreated(MCREvent evt, MCRObject obj) {
077            handleBaseCreated(obj, MCRConfiguration.instance().getBoolean("MCR.Access.AddObjectDefaultRule", true));
078        }
079    
080        /**
081         * This method will be used to update the access rules for SWF for a
082         * MCRObject.
083         * 
084         * @param evt
085         *            the event that occured
086         * @param obj
087         *            the MCRObject that caused the event
088         */
089        protected void handleObjectUpdated(MCREvent evt, MCRObject obj) {
090            handleBaseUpdated(obj, MCRConfiguration.instance().getBoolean("MCR.Access.AddObjectDefaultRule", true));
091        }
092    
093        /**
094         * This method will be used to delete the access rules for SWF for a
095         * MCRObject.
096         * 
097         * @param evt
098         *            the event that occured
099         * @param obj
100         *            the MCRObject that caused the event
101         */
102        protected void handleObjectDeleted(MCREvent evt, MCRObject obj) {
103            handleBaseDeleted(obj);
104        }
105    
106        /**
107         * This method will be used to repair the access rules for SWF for a
108         * MCRObject.
109         * 
110         * @param evt
111         *            the event that occured
112         * @param obj
113         *            the MCRObject that caused the event
114         */
115        protected void handleObjectRepaired(MCREvent evt, MCRObject obj) {
116            // Do nothing
117        }
118    
119        /**
120         * This method will be used to create the access rules for SWF for a
121         * MCRDerivate.
122         * 
123         * @param evt
124         *            the event that occured
125         * @param der
126         *            the MCRDerivate that caused the event
127         */
128        protected void handleDerivateCreated(MCREvent evt, MCRDerivate der) {
129            handleBaseCreated(der, MCRConfiguration.instance().getBoolean("MCR.Access.AddDerivateDefaultRule", true));
130        }
131    
132        /**
133         * This method will be used to update the access rules for SWF for a
134         * MCRDerivate.
135         * 
136         * @param evt
137         *            the event that occured
138         * @param der
139         *            the MCRDerivate that caused the event
140         */
141        protected void handleDerivateUpdated(MCREvent evt, MCRDerivate der) {
142            handleBaseUpdated(der, MCRConfiguration.instance().getBoolean("MCR.Access.AddDerivateDefaultRule", true));
143        }
144    
145        /**
146         * This method will be used to delete the access rules for SWF for a
147         * MCRDerivate.
148         * 
149         * @param evt
150         *            the event that occured
151         * @param der
152         *            the MCRDerivate that caused the event
153         */
154        protected void handleDerivateDeleted(MCREvent evt, MCRDerivate der) {
155            handleBaseDeleted(der);
156        }
157    
158        /**
159         * This method will be used to repair the access rules for SWF for a
160         * MCRDerivate.
161         * 
162         * @param evt
163         *            the event that occured
164         * @param der
165         *            the MCRDerivate that caused the event
166         */
167        protected void handleDerivateRepaired(MCREvent evt, MCRDerivate der) {
168            // Do nothing
169        }
170    
171        private void handleBaseCreated(MCRBase base, boolean addDefaultRules) {
172            // save the start time
173            long t1 = System.currentTimeMillis();
174    
175            // create
176            Collection<String> li = AI.getPermissionsForID(base.getId().getId());
177            int aclsize = 0;
178            if (li != null) {
179                aclsize = li.size();
180            }
181            int rulesize = base.getService().getRulesSize();
182            if ((rulesize == 0) && (aclsize == 0) && addDefaultRules) {
183                setDefaultPermissions(base.getId().getId(), true);
184                LOGGER.warn("The ACL conditions for this object are empty!");
185            }
186            while (0 < rulesize) {
187                org.jdom.Element conditions = base.getService().getRule(0).getCondition();
188                String permission = base.getService().getRule(0).getPermission();
189                if (storedrules.indexOf(permission) != -1) {
190                    MCRAccessManager.addRule(base.getId(), permission, conditions, "");
191                }
192                base.getService().removeRule(0);
193                rulesize--;
194            }
195    
196            // save the stop time
197            long t2 = System.currentTimeMillis();
198            double diff = (t2 - t1) / 1000.0;
199            LOGGER.debug("MCRAccessEventHandler create: done in " + diff + " sec.");
200        }
201    
202        private void handleBaseUpdated(MCRBase base, boolean addDefaultRules) {
203            // save the start time
204            long t1 = System.currentTimeMillis();
205    
206            // update
207            Collection<String> li = AI.getPermissionsForID(base.getId().getId());
208            int aclsize = 0;
209            if (li != null) {
210                aclsize = li.size();
211            }
212            int rulesize = base.getService().getRulesSize();
213            if ((rulesize == 0) && (aclsize == 0) && addDefaultRules) {
214                setDefaultPermissions(base.getId().getId(), false);
215                LOGGER.warn("The ACL conditions for this object was empty!");
216            }
217            if (aclsize == 0) {
218                while (0 < rulesize) {
219                    org.jdom.Element conditions = base.getService().getRule(0).getCondition();
220                    String permission = base.getService().getRule(0).getPermission();
221                    if (storedrules.indexOf(permission) != -1) {
222                        MCRAccessManager.updateRule(base.getId(), permission, conditions, "");
223                    }
224                    base.getService().removeRule(0);
225                    rulesize--;
226                }
227            }
228    
229            // save the stop time
230            long t2 = System.currentTimeMillis();
231            double diff = (t2 - t1) / 1000.0;
232            LOGGER.debug("MCRAccessEventHandler update: done in " + diff + " sec.");
233        }
234    
235        private void handleBaseDeleted(MCRBase base) {
236            // save the start time
237            long t1 = System.currentTimeMillis();
238    
239            // delete
240            MCRAccessManager.removeAllRules(base.getId());
241    
242            // save the stop time
243            long t2 = System.currentTimeMillis();
244            double diff = (t2 - t1) / 1000.0;
245            LOGGER.debug("MCRAccessEventHandler delete: done in " + diff + " sec.");
246        }
247    
248        /**
249         * This method sets Default Rules to all permissions that are configured. if
250         * <i>overwrite</i> = true, then the old permission entries that are in the
251         * database are overwritten, else not.
252         * 
253         * @param obj
254         * @param overwrite
255         */
256        private void setDefaultPermissions(String id, boolean overwrite) {
257            Collection<String> savedPermissions = MCRAccessManager.getPermissionsForID(id);
258            Collection<String> configuredPermissions = AI.getAccessPermissionsFromConfiguration();
259            for (String permission: configuredPermissions) {
260                if (storedrules.indexOf(permission) != -1) {
261                    if (savedPermissions != null && savedPermissions.contains(permission)) {
262                        if (overwrite) {
263                            MCRAccessManager.removeRule(id, permission);
264                            if (permission.startsWith("read"))
265                                MCRAccessManager.addRule(id, permission, readrule, "");
266                            else
267                                MCRAccessManager.addRule(id, permission, editrule, "");
268                        }
269                    } else {
270                        if (permission.startsWith("read"))
271                            MCRAccessManager.addRule(id, permission, readrule, "");
272                        else
273                            MCRAccessManager.addRule(id, permission, editrule, "");
274                    }
275                }
276            }
277        }
278    
279    }