001    package org.mycore.services.acl;
002    
003    import java.io.IOException;
004    import java.io.Reader;
005    import java.io.StringReader;
006    import java.io.UnsupportedEncodingException;
007    import java.net.URLDecoder;
008    import java.util.HashMap;
009    import java.util.Iterator;
010    import java.util.LinkedList;
011    import java.util.List;
012    import java.util.Map;
013    import java.util.Set;
014    
015    import javax.servlet.http.HttpServletRequest;
016    
017    import org.jdom.Content;
018    import org.jdom.Document;
019    import org.jdom.Element;
020    import org.jdom.JDOMException;
021    import org.jdom.input.SAXBuilder;
022    import org.mycore.access.MCRAccessInterface;
023    import org.mycore.access.mcrimpl.MCRAccessControlSystem;
024    import org.mycore.access.mcrimpl.MCRAccessStore;
025    import org.mycore.access.mcrimpl.MCRRuleMapping;
026    import org.mycore.backend.hibernate.tables.MCRACCESS;
027    import org.mycore.backend.hibernate.tables.MCRACCESSRULE;
028    import org.mycore.common.MCRSessionMgr;
029    import org.mycore.frontend.servlets.MCRServlet;
030    
031    import com.ibm.icu.util.StringTokenizer;
032    
033    public class MCRAclEditorStdImpl extends MCRAclEditor {
034        MCRACLHIBAccess HIBA = new MCRACLHIBAccess();
035    
036        MCRACLXMLProcessing XMLProcessing = new MCRACLXMLProcessing();
037    
038        /***************************************************************************
039         * Implementing abstract methods
040         **************************************************************************/
041        @Override
042        public Element getACLEditor(HttpServletRequest request) {
043            LOGGER.debug("Request String: " + request.getQueryString());
044            Element aclEditor = ACLEditor();
045            String type = request.getParameter("editor");
046            String cmd = request.getParameter("cmd");
047    
048            String objIdFilter = request.getParameter("objid");
049            String acPoolFilter = request.getParameter("acpool");
050    
051            String redirectURL = request.getParameter("redir");
052    
053            LOGGER.debug("Redirect: " + redirectURL);
054    
055            if (type == null)
056                type = "permEditor";
057    
058            if (cmd != null)
059                aclEditor.addContent(editorCmd(cmd));
060    
061            if (redirectURL != null && !redirectURL.equals(""))
062                aclEditor.addContent(redirect(redirectURL));
063    
064            aclEditor.addContent(editorType(type));
065            aclEditor.addContent(getFilterElem(objIdFilter, acPoolFilter));
066    
067            return aclEditor;
068        }
069    
070        @Override
071        public Element dataRequest(HttpServletRequest request) {
072            LOGGER.debug("Handling data request.");
073            LOGGER.debug("Query String: " + request.getQueryString());
074    
075            String action = request.getParameter("action");
076            Element elem = null;
077    
078            if (action.equals("setFilter"))
079                elem = setFilter(request);
080            else if (action.equals("getPermEditor"))
081                elem = getPermEditor(request);
082            else if (action.equals("getRuleEditor"))
083                elem = getRuleEditor(request);
084            else if (action.equals("deleteFilter"))
085                elem = getACLEditor(request);
086            else if (action.equals("createNewPerm"))
087                elem = createNewPerm(request);
088            else if (action.equals("createNewRule"))
089                elem = createNewRule(request);
090            else if (action.equals("getRuleAsItems"))
091                elem = getRuleAsItems(request);
092            else if (action.equals("submitPerm"))
093                elem = processPermSubmission(request);
094            else if (action.equals("submitRule"))
095                elem = processRuleSubmission(request);
096            else if (action.equals("delAllRules"))
097                elem = deleteAllRules(request);
098            else if (action.equals("delAllPerms"))
099                elem = deleteAllPerms(request);
100    
101            return elem;
102        }
103    
104        // End implementing abstract methods
105    
106        /***************************************************************************
107         * Mapping stuff
108         **************************************************************************/
109    
110        private Element getPermEditor(HttpServletRequest request) {
111            String objidFilter = request.getParameter("objid");
112            String acpoolFilter = request.getParameter("acpool");
113            String embedded = request.getParameter("emb");
114            String cmd = request.getParameter("cmd");
115    
116            String redirectURL = request.getParameter("redir");
117    
118            LOGGER.debug("Redirect: " + redirectURL);
119            LOGGER.debug("ObjId: " + objidFilter);
120            LOGGER.debug("AcPool: " + acpoolFilter);
121    
122            Element permEditor = getPermission(objidFilter, acpoolFilter);
123    
124            if (redirectURL != null && !redirectURL.equals(""))
125                permEditor.addContent(redirect(redirectURL));
126    
127            if (embedded != null) {
128                permEditor.setAttribute("emb", "true");
129            }
130    
131            if (cmd != null) {
132                permEditor.setAttribute("cmd", cmd);
133            }
134    
135            return permEditor;
136        }
137    
138        private Element getPermission(String objIdFilter, String acPoolFilter) {
139            Element elem = XMLProcessing.access2XML(HIBA.getAccessPermission(objIdFilter, acPoolFilter), true);
140            elem.addContent(getFilterElem(objIdFilter, acPoolFilter));
141    
142            return elem;
143        }
144    
145        private Element getFilterElem(String objIdFilter, String acPoolFilter) {
146            Element elem = XMLProcessing.accessFilter2XML(objIdFilter, acPoolFilter);
147            return elem;
148        }
149    
150        private Element createNewPerm(HttpServletRequest request){
151            String objId = "";
152            try {
153                objId = URLDecoder.decode(request.getParameter("newPermOBJID"),"UTF-8");
154            } catch (UnsupportedEncodingException e) {
155                // TODO Auto-generated catch block
156                e.printStackTrace();
157            }
158            String acPool = request.getParameter("newPermACPOOL");
159            String ruleId = request.getParameter("newPermRID");
160            String uid = MCRServlet.getProperty(request, "uid");
161    
162            LOGGER.debug("ObjId: " + objId);
163            LOGGER.debug("AcPool: " + acPool);
164            LOGGER.debug("RuleId: " + ruleId);
165    
166            MCRRuleMapping perm = XMLProcessing.createRuleMapping(ruleId, acPool, objId);
167            MCRAccessStore.getInstance().createAccessDefinition(perm);
168    
169            String redirectURL = request.getParameter("redir");
170    
171            Element editor;
172    
173            if (redirectURL != null && !redirectURL.equals(""))
174                editor = redirect(redirectURL);
175            else
176                editor = ACLEditor().addContent(editorType("permEditor"));
177    
178            return editor;
179        }
180    
181        private Element processPermSubmission(HttpServletRequest request) {
182            LOGGER.debug("Processing Mapping submission.");
183    
184            Map<String, String[]> parameterMap = request.getParameterMap();
185            Iterator<String> iter = parameterMap.keySet().iterator();
186    
187            LinkedList<MCRRuleMapping> updateAccess = new LinkedList<MCRRuleMapping>();
188            LinkedList<MCRRuleMapping> deleteAccess = new LinkedList<MCRRuleMapping>();
189    
190            final String change = "changed$";
191            final String delete = "deleted$";
192    
193            while (iter.hasNext()) {
194                // key should be in the form changed$_RID$ObjId$AcPool
195                String key = iter.next().trim();
196    
197                LOGGER.debug("Param key: " + key);
198    
199                if (key.startsWith(change)) {
200                    LOGGER.debug("RID changed: " + key);
201    
202                    MCRRuleMapping ruleMapping = extractRuleMapping(parameterMap, change, key);
203    
204                    if (ruleMapping == null) {
205                        LOGGER.debug("ruleMapping NULL!");
206                    }
207    
208                    updateAccess.add(ruleMapping);
209                }
210    
211                if (key.startsWith(delete)) {
212                    LOGGER.debug("RID deleted: " + key);
213    
214                    MCRRuleMapping ruleMapping = extractRuleMapping(parameterMap, delete, key);
215    
216                    deleteAccess.add(ruleMapping);
217                }
218            }
219    
220            HashMap<String, LinkedList<MCRRuleMapping>> diffMap = new HashMap<String, LinkedList<MCRRuleMapping>>();
221            diffMap.put("update", updateAccess);
222            diffMap.put("delete", deleteAccess);
223    
224            HIBA.savePermChanges(diffMap);
225    
226            String redirectURL = request.getParameter("redir");
227    
228            Element editor;
229    
230            if (redirectURL != null && !redirectURL.equals(""))
231                editor = redirect(redirectURL);
232            else
233                editor = ACLEditor().addContent(editorType("permEditor"));
234    
235            return editor;
236        }
237    
238        private Element deleteAllPerms(HttpServletRequest request) {
239            String objidFilter = request.getParameter("objid");
240            String acpoolFilter = request.getParameter("acpool");
241            List<MCRACCESS> accessList = HIBA.getAccessPermission(objidFilter, acpoolFilter);
242            HashMap<String, LinkedList<MCRRuleMapping>> diffMap = new HashMap<String, LinkedList<MCRRuleMapping>>();
243            LinkedList<MCRRuleMapping> deleteAccess = new LinkedList<MCRRuleMapping>();
244            
245            for (Iterator iter = accessList.iterator(); iter.hasNext();) {
246                MCRACCESS currentAcc = (MCRACCESS) iter.next();
247                String rid = currentAcc.getRule().getRid();
248                String acpool = currentAcc.getKey().getAcpool();
249                String objid = currentAcc.getKey().getObjid();
250                
251                
252    
253                MCRRuleMapping ruleMapping = XMLProcessing.createRuleMapping(rid, acpool, objid);
254                deleteAccess.add(ruleMapping);
255            }
256            diffMap.put("delete", deleteAccess);
257    
258            HIBA.savePermChanges(diffMap);
259    
260            String redirectURL = request.getParameter("redir");
261            LOGGER.debug("Redirect URL: " + redirectURL);
262    
263            Element editor;
264    
265            if (redirectURL != null && !redirectURL.equals(""))
266                editor = redirect(redirectURL);
267            else {
268                editor = ACLEditor().addContent(editorType("permEditor"));
269                editor.addContent(getFilterElem(objidFilter, acpoolFilter));
270            }
271    
272            return editor;
273        }
274    
275        private MCRRuleMapping extractRuleMapping(Map<String, String[]> parameterMap, String action, String key) {
276            StringTokenizer token = new StringTokenizer(key.substring(action.length() - 1), "$");
277            String objId = token.nextToken();
278            String acPool = token.nextToken();
279            String ruleId = parameterMap.get(key)[0];
280    
281            MCRRuleMapping ruleMapping = XMLProcessing.createRuleMapping(ruleId, acPool, objId);
282            LOGGER.debug("ObjId: " + ruleMapping.getObjId());
283            LOGGER.debug("AcPool: " + ruleMapping.getPool());
284            LOGGER.debug("RuleId: " + ruleMapping.getRuleId());
285            return ruleMapping;
286        }
287    
288        private Element setFilter(HttpServletRequest request) {
289            String objIdFilter = request.getParameter("ObjIdFilter");
290            String acPoolFilter = request.getParameter("AcPoolFilter");
291    
292            if (objIdFilter.equals(""))
293                objIdFilter = null;
294            if (acPoolFilter.equals(""))
295                acPoolFilter = null;
296    
297            LOGGER.debug("ObjIdFilter: " + objIdFilter);
298            LOGGER.debug("AcPoolFilter: " + acPoolFilter);
299    
300            Element editor = ACLEditor();
301            editor.addContent(editorType("permEditor"));
302            editor.addContent(getFilterElem(objIdFilter, acPoolFilter));
303            return editor;
304        }
305    
306        // End Mapping stuff
307    
308        /***************************************************************************
309         * Rule stuff
310         **************************************************************************/
311    
312        private Element getRuleEditor(HttpServletRequest request) {
313            Element elem = XMLProcessing.ruleSet2XML(HIBA.getAccessRule());
314            return elem;
315        }
316    
317        private Element createNewRule(HttpServletRequest request) {
318            MCRACCESSRULE accessRule = new MCRACCESSRULE();
319            MCRAccessInterface AI = MCRAccessControlSystem.instance();
320            String rule = request.getParameter("newRule").trim();
321            String desc = request.getParameter("newRuleDesc");
322            String uid = MCRSessionMgr.getCurrentSession().getCurrentUserID();
323    
324            if (rule.startsWith("<"))
325                rule = ruleFromXML(rule);
326    
327            accessRule.setRule(rule);
328            accessRule.setDescription(desc);
329            
330            LOGGER.debug("User ID: " + uid);
331    
332            AI.createRule(accessRule.getRule(), uid, accessRule.getDescription());
333    
334            LOGGER.debug("Rule: " + rule);
335            LOGGER.debug("Desc: " + desc);
336    
337            String redirectURL = request.getParameter("redir");
338            LOGGER.debug("Redirect URL: " + redirectURL);
339    
340            Element editor;
341    
342            if (redirectURL != null && !redirectURL.equals(""))
343                editor = redirect(redirectURL);
344            else
345                editor = ACLEditor().addContent(editorType("ruleEditor"));
346            
347            return editor;
348        }
349    
350        private String ruleFromXML(String rule) {
351            SAXBuilder saxBuilder = new SAXBuilder("org.apache.xerces.parsers.SAXParser");
352            Reader stringReader = new StringReader(rule);
353            Document jdomDocument = null;
354    
355            try {
356                jdomDocument = saxBuilder.build(stringReader);
357            } catch (JDOMException e) {
358                e.printStackTrace();
359            } catch (IOException e) {
360                e.printStackTrace();
361            }
362    
363            MCRAccessInterface AI = MCRAccessControlSystem.instance();
364    
365            return AI.getNormalizedRuleString(jdomDocument.getRootElement());
366        }
367    
368        private Element getRuleAsItems(HttpServletRequest request) {
369            Element elem = XMLProcessing.ruleSet2Items(HIBA.getAccessRule());
370            return elem;
371        }
372    
373        private Element processRuleSubmission(HttpServletRequest request) {
374            LOGGER.debug("Processing Rule submission.");
375            
376            String uid = MCRServlet.getProperty(request, "uid");
377            Map<String, String[]> parameterMap = request.getParameterMap();
378            Set<String> keySet = parameterMap.keySet();
379            Iterator<String> iter = keySet.iterator();
380    
381            LinkedList<MCRACCESSRULE> updateRule = new LinkedList<MCRACCESSRULE>();
382            LinkedList<String> deleteRule = new LinkedList<String>();
383    
384            final String change = "changed$";
385            final String delete = "deleted$";
386    
387            String ridOld = "";
388            String currentRid = "";
389    
390            while (iter.hasNext()) {
391                String key = iter.next().trim();
392                MCRACCESSRULE ruleMapping = new MCRACCESSRULE();
393    
394                if (key.contains(change) || key.contains(delete)) {
395                    LOGGER.debug("Param key: " + key);
396    
397                    currentRid = new String(key.substring(key.lastIndexOf("$") + 1, key.length()));
398    
399                    if (!currentRid.equals(ridOld)) {
400                        if (key.startsWith(change)) {
401                            ruleMapping = extractAccessRule(parameterMap, change, key, currentRid);
402                            LOGGER.debug("Rule changed: " + key);
403                            updateRule.add(ruleMapping);
404                        } else if (key.startsWith(delete)) {
405                            LOGGER.debug("Delete Rule: " + key);
406                            deleteRule.add(currentRid);
407                        }
408                    }
409    
410                    ridOld = new String(currentRid);
411                }
412            }
413    
414            HashMap diffMap = new HashMap();
415            diffMap.put("update", updateRule);
416            diffMap.put("delete", deleteRule);
417    
418            HIBA.saveRuleChanges(diffMap);
419            String redirectURL = request.getParameter("redir");
420    
421            Element editor;
422    
423            if (redirectURL != null && !redirectURL.equals(""))
424                editor = redirect(redirectURL);
425            else
426                editor = ACLEditor().addContent(editorType("ruleEditor"));
427    
428            return editor;
429        }
430    
431        private Element deleteAllRules(HttpServletRequest request) {
432            LOGGER.debug("Delete all rules.");
433    
434            String uid = MCRServlet.getProperty(request, "uid");
435            HashMap diffMap = new HashMap();
436    
437            List<MCRACCESSRULE> ruleList = HIBA.getAccessRule();
438            LinkedList<String> deleteRule = new LinkedList<String>();
439    
440            for (Iterator iter = ruleList.iterator(); iter.hasNext();) {
441                MCRACCESSRULE rule = (MCRACCESSRULE) iter.next();
442                String currentRid = rule.getRid();
443                LOGGER.debug("Delete: " + currentRid);
444                deleteRule.add(currentRid);
445            }
446            diffMap.put("delete", deleteRule);
447    
448            HIBA.saveRuleChanges(diffMap);
449            String redirectURL = request.getParameter("redir");
450    
451            Element editor;
452    
453            if (redirectURL != null && !redirectURL.equals(""))
454                editor = redirect(redirectURL);
455            else
456                editor = ACLEditor().addContent(editorType("ruleEditor"));
457    
458            return editor;
459        }
460    
461        private MCRACCESSRULE extractAccessRule(Map<String, String[]> parameterMap, String action, String key, String rid) {
462            final String RULE = "Rule$";
463            final String DESC = "RuleDesc$";
464    
465            MCRACCESSRULE accessrule = new MCRACCESSRULE();
466    
467            String ruleString = null;
468            String ruleDesc = null;
469    
470            // Checking which case occur
471            // | rule | description
472            // --------+----------+-----------------
473            // changed | yes | no
474            // | no | yes
475            // | yes | yes
476            // 
477            if (key.contains(RULE)) {
478                ruleString = parameterMap.get(key)[0];
479    
480                if (parameterMap.get(DESC + rid) != null)
481                    ruleDesc = parameterMap.get(DESC + rid)[0];
482                else if (parameterMap.get(action + DESC + rid) != null)
483                    ruleDesc = parameterMap.get(action + DESC + rid)[0];
484                else
485                    ruleDesc = "";
486    
487            } else if (key.contains(DESC)) {
488                ruleDesc = parameterMap.get(key)[0];
489    
490                if (parameterMap.get(RULE + rid) != null)
491                    ruleString = parameterMap.get(RULE + rid)[0];
492                else if (parameterMap.get(action + RULE + rid) != null)
493                    ruleString = parameterMap.get(action + RULE + rid)[0];
494                else
495                    ruleString = "";
496    
497            } else
498                LOGGER.debug("Wrong key: " + key);
499    
500            accessrule.setRid(rid);
501            accessrule.setRule(ruleString);
502            accessrule.setDescription(ruleDesc);
503    
504            return accessrule;
505        }
506    
507        // End Rule stuff
508    
509        public Element ACLEditor() {
510            Element element = new Element("mcr_acl_editor");
511            return element;
512        }
513    
514        private Content editorType(String type) {
515            Element editorType = new Element("editor");
516            editorType.addContent(type);
517            return editorType;
518        }
519    
520        private Content editorCmd(String cmd) {
521            Element editorType = new Element("cmd");
522            editorType.addContent(cmd);
523            return editorType;
524        }
525    
526        private Element redirect(String url) {
527            Element redirect = new Element("redirect");
528            redirect.addContent(url);
529            return redirect;
530        }
531    
532    }