001    /*
002     * 
003     * $Revision: 1.11 $ $Date: 2008/11/27 07:58:28 $
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 org.mycore.frontend.cli;
025    
026    import static org.mycore.common.MCRConstants.DEFAULT_ENCODING;
027    import static org.mycore.common.MCRConstants.XLINK_NAMESPACE;
028    import static org.mycore.common.MCRConstants.XSI_NAMESPACE;
029    
030    import java.io.File;
031    import java.io.FileOutputStream;
032    import java.util.Collection;
033    import java.util.List;
034    
035    import org.apache.log4j.Logger;
036    import org.jdom.Document;
037    import org.jdom.Element;
038    import org.jdom.output.Format;
039    import org.jdom.output.XMLOutputter;
040    import org.mycore.access.MCRAccessInterface;
041    import org.mycore.access.MCRAccessManager;
042    import org.mycore.common.MCRException;
043    import org.mycore.common.xml.MCRXMLHelper;
044    
045    /**
046     * This class provides a set of commands for the org.mycore.access management
047     * which can be used by the command line interface.
048     * 
049     * @author Heiko Helmbrecht
050     * @author Jens Kupferschmidt
051     * @version $Revision: 1.11 $ $Date: 2008/11/27 07:58:28 $
052     */
053    public class MCRAccessCommands extends MCRAbstractCommands {
054        /** The logger */
055        private static Logger LOGGER = Logger.getLogger(MCRAccessCommands.class.getName());
056    
057        /**
058         * The constructor.
059         */
060        public MCRAccessCommands() {
061            super();
062    
063            MCRCommand com = null;
064    
065            com = new MCRCommand("load permissions data from file {0}",
066                    "org.mycore.frontend.cli.MCRAccessCommands.loadPermissionsFromFile String",
067                    "The command loads the permissions data of the access control system with data from the file {0}.");
068            command.add(com);
069    
070            com = new MCRCommand("list all permissions", "org.mycore.frontend.cli.MCRAccessCommands.listAllPermissions",
071                    "List all permission entries.");
072            command.add(com);
073    
074            com = new MCRCommand("delete permission {0}", "org.mycore.frontend.cli.MCRAccessCommands.deletePermission String",
075                    "Remove a named permission entriy from the Access Control System.");
076            command.add(com);
077    
078            com = new MCRCommand("delete all permissions", "org.mycore.frontend.cli.MCRAccessCommands.deleteAllPermissions",
079                    "Remove all permission entries from the Access Control System.");
080            command.add(com);
081    
082            com = new MCRCommand("export all permissions to file {0}",
083                    "org.mycore.frontend.cli.MCRAccessCommands.exportAllPermissionsToFile String",
084                    "Export all permissions from the Access Control System to the file {0}.");
085            command.add(com);
086    
087            com = new MCRCommand("update permission {0} for id {1} with rulefile {2} described by {3}",
088                    "org.mycore.frontend.cli.MCRAccessCommands.permissionUpdateForID String String String String",
089                    "The command updates access rule for a given id of a given permission with a given special rule");
090            command.add(com);
091    
092            com = new MCRCommand("update permission {0} for id {1} with rulefile {2}",
093                    "org.mycore.frontend.cli.MCRAccessCommands.permissionUpdateForID String String String",
094                    "The command updates access rule for a given id of a given permission with a given special rule");
095            command.add(com);
096    
097            com = new MCRCommand("update permission {0} for selected with rulefile {2} described by {3}",
098                    "org.mycore.frontend.cli.MCRAccessCommands.permissionUpdateForSelected String String String",
099                    "The command updates access rule for a given permission and all ids of a given MCRObject-Type with a given special rule");
100            command.add(com);
101    
102            com = new MCRCommand("update permission {0} for selected with rulefile {2}",
103                    "org.mycore.frontend.cli.MCRAccessCommands.permissionUpdateForSelected String String",
104                    "The command updates access rule for a given permission and all ids of a given MCRObject-Type with a given special rule");
105            command.add(com);
106    
107            com = new MCRCommand("delete permission {0} for id {1}",
108                    "org.mycore.frontend.cli.MCRAccessCommands.permissionDeleteForID String String",
109                    "The command delete access rule for a given id of a given permission");
110            command.add(com);
111    
112            com = new MCRCommand("delete all permissions for id {1}",
113                    "org.mycore.frontend.cli.MCRAccessCommands.permissionDeleteAllForID String",
114                    "The command delete all access rules for a given id");
115            command.add(com);
116    
117            com = new MCRCommand("delete permission {0} for selected",
118                    "org.mycore.frontend.cli.MCRAccessCommands.permissionDeleteForSelected String",
119                    "The command delete access rule for a query selected set of object ids of a given permission");
120            command.add(com);
121    
122            com = new MCRCommand("delete all permissions for selected",
123                    "org.mycore.frontend.cli.MCRAccessCommands.permissionDeleteAllForSelected",
124                    "The command delete all access rules for a query selected set of object ids");
125            command.add(com);
126    
127            com = new MCRCommand(
128                    "set website read only {0}",
129                    "org.mycore.frontend.MCRWebsiteWriteProtection.activate String",
130                    "Usage: <command> <message>, This command set the whole website into read only mode and provides the given message to users. Nobody, except super user can write on system, using web frontend");
131            command.add(com);
132    
133            com = new MCRCommand(
134                    "set website read only",
135                    "org.mycore.frontend.MCRWebsiteWriteProtection.activate",
136                    "This command set the whole website into read only mode. An already configurated message will be displayed to users. Nobody, except super user can write on system, using web frontend");
137            command.add(com);
138    
139            com = new MCRCommand("unset website read only", "org.mycore.frontend.MCRWebsiteWriteProtection.deactivate",
140                    "This command removes the write protection (read only) from website. After unsetting anybody can write as usual, using web frontend");
141            command.add(com);
142        }
143    
144        /**
145         * Check the file name
146         * 
147         * @param filename
148         *            the filename of the user data input
149         * @return true if the file name is okay
150         */
151        private static final boolean checkFilename(String filename) {
152            if (!filename.endsWith(".xml")) {
153                LOGGER.warn(filename + " ignored, does not end with *.xml");
154    
155                return false;
156            }
157    
158            if (!new File(filename).isFile()) {
159                LOGGER.warn(filename + " ignored, is not a file.");
160    
161                return false;
162            }
163    
164            return true;
165        }
166    
167        /**
168         * This method sets the new permissions given in a certain file
169         * 
170         * @param filename
171         *            the filename of the file that contains the mcrpermissions
172         * 
173         */
174        @SuppressWarnings("unchecked")
175        public static void createPermissionsFromFile(String filename) {
176            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
177            if (!checkFilename(filename)) {
178                return;
179            }
180            File input = new File(filename);
181    
182            LOGGER.info("Reading file " + input + " ...");
183    
184            org.jdom.Document doc = MCRXMLHelper.parseURI(input.toURI(), true);
185            org.jdom.Element rootelm = doc.getRootElement();
186    
187            if (!rootelm.getName().equals("mcrpermissions")) {
188                throw new MCRException("The data are not for mcrpermissions.");
189            }
190    
191            List<Element> listelm = rootelm.getChildren("mcrpermission");
192    
193            for (Element mcrpermission : listelm) {
194                String permissionName = mcrpermission.getAttributeValue("name").trim();
195                String ruleDescription = mcrpermission.getAttributeValue("ruledescription");
196                if (ruleDescription == null)
197                    ruleDescription = "";
198                Element rule = (Element) mcrpermission.getChild("condition").clone();
199                AI.addRule(permissionName, rule, ruleDescription);
200            }
201        }
202    
203        /**
204         * This method deletes the old permissions (if given any) and sets the new
205         * permissions given in a certain file
206         * 
207         * @param filename
208         *            the filename of the file that contains the mcrpermissions
209         * @see #updatePermissionsFromFile(String)
210         */
211        public static void loadPermissionsFromFile(String filename) throws Exception {
212            createPermissionsFromFile(filename);
213        }
214    
215        /**
216         * delete all permissions
217         */
218        public static void deleteAllPermissions() throws Exception {
219            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
220            for (String permission : (List<String>) AI.getPermissions()) {
221                AI.removeRule(permission);
222            }
223        }
224    
225        /**
226         * delete the permission {0}
227         * 
228         * @param permission
229         *            the name of the permission
230         */
231        public static void deletePermission(String permission) throws Exception {
232            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
233            AI.removeRule(permission);
234        }
235    
236        /**
237         * This method invokes MCRUserMgr.getAllPrivileges() and retrieves a
238         * ArrayList of all privileges stored in the persistent datastore.
239         */
240        public static void listAllPermissions() throws MCRException {
241            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
242            Collection<String> permissions = AI.getPermissions();
243            boolean noPermissionsDefined = true;
244            for (String permission : permissions) {
245                noPermissionsDefined = false;
246                String description = AI.getRuleDescription(permission);
247                if (description.equals(""))
248                    description = "No description";
249                org.jdom.Element rule = AI.getRule(permission);
250                LOGGER.info("       " + permission);
251                LOGGER.info("           " + description);
252                if (rule != null) {
253                    org.jdom.output.XMLOutputter o = new org.jdom.output.XMLOutputter();
254                    LOGGER.info("           " + o.outputString(rule));
255                }
256            }
257            if (noPermissionsDefined)
258                LOGGER.warn("No permissions defined");
259            LOGGER.info("");
260        }
261    
262        /**
263         * This method just export the permissions to a file
264         * 
265         * @param filename
266         *            the file written to
267         */
268        public static final void exportAllPermissionsToFile(String filename) throws Exception {
269            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
270    
271            Element mcrpermissions = new Element("mcrpermissions");
272            mcrpermissions.addNamespaceDeclaration(XSI_NAMESPACE);
273            mcrpermissions.addNamespaceDeclaration(XLINK_NAMESPACE);
274            mcrpermissions.setAttribute("noNamespaceSchemaLocation", "MCRPermissions.xsd", XSI_NAMESPACE);
275            Document doc = new Document(mcrpermissions);
276            Collection<String> permissions = AI.getPermissions();
277            for (String permission : permissions) {
278                Element mcrpermission = new Element("mcrpermission");
279                mcrpermission.setAttribute("name", permission);
280                String ruleDescription = AI.getRuleDescription(permission);
281                if (!ruleDescription.equals("")) {
282                    mcrpermission.setAttribute("ruledescription", ruleDescription);
283                }
284                Element rule = AI.getRule(permission);
285                mcrpermission.addContent(rule);
286                mcrpermissions.addContent(mcrpermission);
287            }
288            File file = new File(filename);
289            if (file.exists()) {
290                LOGGER.warn("File " + filename + " yet exists, overwrite.");
291            }
292            FileOutputStream fos = new FileOutputStream(file);
293            LOGGER.info("Writing to file " + filename + " ...");
294            String mcr_encoding = CONFIG.getString("MCR.Metadata.DefaultEncoding", DEFAULT_ENCODING);
295            XMLOutputter out = new XMLOutputter(Format.getPrettyFormat().setEncoding(mcr_encoding));
296            out.output(doc, fos);
297        }
298    
299        private static Element getRuleFromFile(String fileName) {
300            if (!checkFilename(fileName)) {
301                LOGGER.warn("Wrong file format or file doesn't exist");
302                return null;
303            }
304            File input = new File(fileName);
305            Document ruleDom = MCRXMLHelper.parseURI(input.toURI());
306            Element rule = ruleDom.getRootElement();
307            if (!rule.getName().equals("condition")) {
308                LOGGER.warn("ROOT element is not valid, a valid rule would be for example:");
309                LOGGER.warn("<condition format=\"xml\"><boolean operator=\"true\" /></condition>");
310                return null;
311            }
312            return rule;
313        }
314    
315        /**
316         * updates the permission for a given id and a given permission type with a
317         * given rule
318         * 
319         * @param permission
320         *            String type of permission like read, writedb, etc.
321         * @param id
322         *            String the id of the object the rule is assigned to
323         * @param strFileRule
324         *            String the path to the xml file, that contains the rule
325         */
326        public static void permissionUpdateForID(String permission, String id, String strFileRule) {
327            permissionUpdateForID(permission, id, strFileRule, "");
328        }
329    
330        /**
331         * updates the permission for a given id and a given permission type with a
332         * given rule
333         * 
334         * @param permission
335         *            String type of permission like read, writedb, etc.
336         * @param id
337         *            String the id of the object the rule is assigned to
338         * @param strFileRule
339         *            String the path to the xml file, that contains the rule
340         * @param description
341         *            String give a special description, if the semantics of your
342         *            rule is multiple used
343         */
344        public static void permissionUpdateForID(String permission, String id, String strFileRule, String description) {
345            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
346            Element rule = getRuleFromFile(strFileRule);
347            if (rule == null)
348                return;
349            AI.addRule(id, permission, rule, description);
350            return;
351        }
352    
353        /**
354         * updates the permissions for all ids of a given MCRObjectID-Type with a
355         * given rule and a given permission
356         * 
357         * @param permission
358         *            String type of permission like read, writedb, etc.
359         * @param documentType
360         *            String a MCRObjectID-Type like document, disshab, etc.
361         * @param strFileRule
362         *            String the path to the xml file, that contains the rule
363         */
364        public static void permissionUpdateForSelected(String permission, String strFileRule) {
365            permissionUpdateForSelected(permission, strFileRule, "");
366        }
367    
368        /**
369         * updates the permissions for all ids of a given MCRObjectID-Type and for a
370         * given permission type with a given rule
371         * 
372         * @param permission
373         *            String type of permission like read, writedb, etc.
374         * @param documentType
375         *            String a MCRObjectID-Type like document, disshab, etc.
376         * @param strFileRule
377         *            String the path to the xml file, that contains the rule
378         * @param description
379         *            String give a special description, if the semantics of your
380         *            rule is multiple used
381         */
382        public static void permissionUpdateForSelected(String permission, String strFileRule, String description) {
383            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
384            Element rule = getRuleFromFile(strFileRule);
385            if (rule == null)
386                return;
387            for (String id : MCRObjectCommands.getSelectedObjectIDs()) {
388                AI.addRule(id, permission, rule, description);
389            }
390        }
391    
392        /**
393         * delete a given permission for a given id
394         * 
395         * @param permission
396         *            String type of permission like read, writedb, etc.
397         * @param id
398         *            String the id of the object the rule is assigned to
399         */
400        public static void permissionDeleteForID(String permission, String id) {
401            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
402            AI.removeRule(id, permission);
403            return;
404        }
405    
406        /**
407         * delete all permissions for a given id
408         * 
409         * @param id
410         *            String the id of the object the rule is assigned to
411         */
412        public static void permissionDeleteAllForID(String id) {
413            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
414            AI.removeAllRules(id);
415            return;
416        }
417    
418        /**
419         * delete all permissions for all selected objects
420         * 
421         * @param permission
422         *            String type of permission like read, writedb, etc.
423         * @see MCRObjectCommands#getSelectedObjectIDs()
424         */
425        public static void permissionDeleteForSelected(String permission) {
426            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
427            for (String id : MCRObjectCommands.getSelectedObjectIDs()) {
428                AI.removeRule(id, permission);
429            }
430            return;
431        }
432    
433        /**
434         * delete all permissions for all selected objects
435         * 
436         * @see MCRObjectCommands#getSelectedObjectIDs()
437         */
438        public static void permissionDeleteAllForSelected() {
439            MCRAccessInterface AI = MCRAccessManager.getAccessImpl();
440            for (String id : MCRObjectCommands.getSelectedObjectIDs()) {
441                AI.removeAllRules(id);
442            }
443            return;
444        }
445    
446    }