View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.frontend.cli;
20  
21  import static org.mycore.common.MCRConstants.DEFAULT_ENCODING;
22  import static org.mycore.common.MCRConstants.XLINK_NAMESPACE;
23  import static org.mycore.common.MCRConstants.XSI_NAMESPACE;
24  
25  import java.io.File;
26  import java.io.FileOutputStream;
27  import java.util.Collection;
28  import java.util.List;
29  
30  import org.apache.logging.log4j.LogManager;
31  import org.apache.logging.log4j.Logger;
32  import org.jdom2.Document;
33  import org.jdom2.Element;
34  import org.jdom2.output.Format;
35  import org.jdom2.output.XMLOutputter;
36  import org.mycore.access.MCRRuleAccessInterface;
37  import org.mycore.access.MCRAccessManager;
38  import org.mycore.common.MCRException;
39  import org.mycore.common.config.MCRConfiguration2;
40  import org.mycore.common.content.MCRFileContent;
41  import org.mycore.common.xml.MCRXMLParserFactory;
42  import org.mycore.frontend.MCRWebsiteWriteProtection;
43  import org.mycore.frontend.cli.annotation.MCRCommand;
44  import org.mycore.frontend.cli.annotation.MCRCommandGroup;
45  
46  /**
47   * This class provides a set of commands for the org.mycore.access management
48   * which can be used by the command line interface.
49   * 
50   * @author Heiko Helmbrecht
51   * @author Jens Kupferschmidt
52   * @version $Revision: 1.11 $ $Date: 2008/11/27 07:58:28 $
53   */
54  
55  @MCRCommandGroup(name = "Access Commands")
56  public class MCRAccessCommands extends MCRAbstractCommands {
57      /** The logger */
58      private static Logger LOGGER = LogManager.getLogger(MCRAccessCommands.class.getName());
59  
60      /**
61       * Check the file name
62       * 
63       * @param filename
64       *            the filename of the user data input
65       * @return true if the file name is okay
66       */
67      private static boolean checkFilename(String filename) {
68          if (!filename.endsWith(".xml")) {
69              LOGGER.warn("{} ignored, does not end with *.xml", filename);
70              return false;
71          }
72  
73          if (!new File(filename).isFile()) {
74              LOGGER.warn("{} ignored, is not a file.", filename);
75              return false;
76          }
77          return true;
78      }
79  
80      /**
81       * This method sets the new permissions given in a certain file
82       * 
83       * @param filename
84       *            the filename of the file that contains the mcrpermissions
85       * 
86       */
87      public static void createPermissionsFromFile(String filename) throws Exception {
88          MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
89          if (!checkFilename(filename)) {
90              return;
91          }
92          LOGGER.info("Reading file {} ...", filename);
93  
94          Document doc = MCRXMLParserFactory.getValidatingParser().parseXML(new MCRFileContent(filename));
95          Element rootelm = doc.getRootElement();
96  
97          if (!rootelm.getName().equals("mcrpermissions")) {
98              throw new MCRException("The data are not for mcrpermissions.");
99          }
100 
101         List<Element> listelm = rootelm.getChildren("mcrpermission");
102 
103         for (Element mcrpermission : listelm) {
104             String permissionName = mcrpermission.getAttributeValue("name").trim();
105             String ruleDescription = mcrpermission.getAttributeValue("ruledescription");
106             if (ruleDescription == null) {
107                 ruleDescription = "";
108             }
109             Element rule = mcrpermission.getChild("condition").clone();
110             String objectid = mcrpermission.getAttributeValue("objectid");
111             if (objectid == null) {
112                 accessImpl.addRule(permissionName, rule, ruleDescription);
113             } else {
114                 accessImpl.addRule(objectid, permissionName, rule, ruleDescription);
115             }
116         }
117     }
118 
119     /**
120      * This method deletes the old permissions (if given any) and sets the new
121      * permissions given in a certain file
122      * 
123      * @param filename
124      *            the filename of the file that contains the mcrpermissions
125      * @see #createPermissionsFromFile(String)
126      */
127     @MCRCommand(syntax = "load permissions data from file {0}",
128         help = "The command loads the permissions data of the access control system with data from the file {0}.",
129         order = 10)
130     public static void loadPermissionsFromFile(String filename) throws Exception {
131         createPermissionsFromFile(filename);
132     }
133 
134     /**
135      * delete all permissions
136      */
137     @MCRCommand(syntax = "delete all permissions",
138         help = "Remove all permission entries from the Access Control System.",
139         order = 40)
140     public static void deleteAllPermissions() throws Exception {
141         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
142         for (String permission : accessImpl.getPermissions()) {
143             accessImpl.removeRule(permission);
144         }
145     }
146 
147     /**
148      * delete the permission {0}
149      * 
150      * @param permission
151      *            the name of the permission
152      */
153     @MCRCommand(syntax = "delete permission {0}",
154         help = "Remove a named permission entriy from the Access Control System.",
155         order = 30)
156     public static void deletePermission(String permission) throws Exception {
157         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
158         accessImpl.removeRule(permission);
159     }
160 
161     /**
162      * This method invokes MCRUserMgr.getAllPrivileges() and retrieves a
163      * ArrayList of all privileges stored in the persistent datastore.
164      */
165     @MCRCommand(syntax = "list all permissions", help = "List all permission entries.", order = 20)
166     public static void listAllPermissions() throws MCRException {
167         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
168         Collection<String> permissions = accessImpl.getPermissions();
169         boolean noPermissionsDefined = true;
170         for (String permission : permissions) {
171             noPermissionsDefined = false;
172             String description = accessImpl.getRuleDescription(permission);
173             if (description.equals("")) {
174                 description = "No description";
175             }
176             Element rule = accessImpl.getRule(permission);
177             LOGGER.info("       {}", permission);
178             LOGGER.info("           {}", description);
179             if (rule != null) {
180                 XMLOutputter o = new XMLOutputter();
181                 LOGGER.info("           {}", o.outputString(rule));
182             }
183         }
184         if (noPermissionsDefined) {
185             LOGGER.warn("No permissions defined");
186         }
187         LOGGER.info("");
188     }
189 
190     /**
191      * This method just export the permissions to a file
192      * 
193      * @param filename
194      *            the file written to
195      */
196     @MCRCommand(syntax = "export all permissions to file {0}",
197         help = "Export all permissions from the Access Control System to the file {0}.",
198         order = 50)
199     public static void exportAllPermissionsToFile(String filename) throws Exception {
200         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
201 
202         Element mcrpermissions = new Element("mcrpermissions");
203         mcrpermissions.addNamespaceDeclaration(XSI_NAMESPACE);
204         mcrpermissions.addNamespaceDeclaration(XLINK_NAMESPACE);
205         mcrpermissions.setAttribute("noNamespaceSchemaLocation", "MCRPermissions.xsd", XSI_NAMESPACE);
206         Document doc = new Document(mcrpermissions);
207         Collection<String> permissions = accessImpl.getPermissions();
208         for (String permission : permissions) {
209             Element mcrpermission = new Element("mcrpermission");
210             mcrpermission.setAttribute("name", permission);
211             String ruleDescription = accessImpl.getRuleDescription(permission);
212             if (!ruleDescription.equals("")) {
213                 mcrpermission.setAttribute("ruledescription", ruleDescription);
214             }
215             Element rule = accessImpl.getRule(permission);
216             mcrpermission.addContent(rule);
217             mcrpermissions.addContent(mcrpermission);
218         }
219         File file = new File(filename);
220         if (file.exists()) {
221             LOGGER.warn("File {} yet exists, overwrite.", filename);
222         }
223         FileOutputStream fos = new FileOutputStream(file);
224         LOGGER.info("Writing to file {} ...", filename);
225         String mcrEncoding = MCRConfiguration2.getString("MCR.Metadata.DefaultEncoding").orElse(DEFAULT_ENCODING);
226         XMLOutputter out = new XMLOutputter(Format.getPrettyFormat().setEncoding(mcrEncoding));
227         out.output(doc, fos);
228     }
229 
230     private static Element getRuleFromFile(String fileName) throws Exception {
231         if (!checkFilename(fileName)) {
232             LOGGER.warn("Wrong file format or file doesn't exist");
233             return null;
234         }
235         Document ruleDom = MCRXMLParserFactory.getParser().parseXML(new MCRFileContent(fileName));
236         Element rule = ruleDom.getRootElement();
237         if (!rule.getName().equals("condition")) {
238             LOGGER.warn("ROOT element is not valid, a valid rule would be for example:");
239             LOGGER.warn("<condition format=\"xml\"><boolean operator=\"true\" /></condition>");
240             return null;
241         }
242         return rule;
243     }
244 
245     /**
246      * updates the permission for a given id and a given permission type with a
247      * given rule
248      * 
249      * @param permission
250      *            String type of permission like read, writedb, etc.
251      * @param id
252      *            String the id of the object the rule is assigned to
253      * @param strFileRule
254      *            String the path to the xml file, that contains the rule
255      */
256     @MCRCommand(syntax = "update permission {0} for id {1} with rulefile {2}",
257         help = "The command updates access rule for a given id of a given permission with a given special rule",
258         order = 70)
259     public static void permissionUpdateForID(String permission, String id, String strFileRule) throws Exception {
260         permissionUpdateForID(permission, id, strFileRule, "");
261     }
262 
263     /**
264      * updates the permission for a given id and a given permission type with a
265      * given rule
266      * 
267      * @param permission
268      *            String type of permission like read, writedb, etc.
269      * @param id
270      *            String the id of the object the rule is assigned to
271      * @param strFileRule
272      *            String the path to the xml file, that contains the rule
273      * @param description
274      *            String give a special description, if the semantics of your
275      *            rule is multiple used
276      */
277     @MCRCommand(syntax = "update permission {0} for id {1} with rulefile {2} described by {3}",
278         help = "The command updates access rule for a given id of a given permission with a given special rule",
279         order = 60)
280     public static void permissionUpdateForID(String permission, String id, String strFileRule, String description)
281         throws Exception {
282         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
283         Element rule = getRuleFromFile(strFileRule);
284         if (rule == null) {
285             return;
286         }
287         accessImpl.addRule(id, permission, rule, description);
288     }
289 
290     /**
291      * updates the permissions for all ids of a given MCRObjectID-Type with a
292      * given rule and a given permission
293      * 
294      * @param permission
295      *            String type of permission like read, writedb, etc.
296      * @param strFileRule
297      *            String the path to the xml file, that contains the rule
298      */
299     @MCRCommand(
300         syntax = "update permission {0} for selected with rulefile {1}",
301         help = "The command updates access rule for a given permission and all ids "
302             + "of a given MCRObject-Type with a given special rule",
303         order = 90)
304     public static void permissionUpdateForSelected(String permission, String strFileRule) throws Exception {
305         permissionUpdateForSelected(permission, strFileRule, "");
306     }
307 
308     /**
309      * updates the permissions for all ids of a given MCRObjectID-Type and for a
310      * given permission type with a given rule
311      * 
312      * @param permission
313      *            String type of permission like read, writedb, etc.
314      * @param strFileRule
315      *            String the path to the xml file, that contains the rule
316      * @param description
317      *            String give a special description, if the semantics of your
318      *            rule is multiple used
319      */
320 
321     @MCRCommand(
322         syntax = "update permission {0} for selected with rulefile {1} described by {2}",
323         help = "The command updates access rule for a given permission and all ids "
324             + "of a given MCRObject-Type with a given special rule",
325         order = 80)
326     public static void permissionUpdateForSelected(String permission, String strFileRule, String description)
327         throws Exception {
328         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
329         Element rule = getRuleFromFile(strFileRule);
330         if (rule == null) {
331             return;
332         }
333         for (String id : MCRObjectCommands.getSelectedObjectIDs()) {
334             accessImpl.addRule(id, permission, rule, description);
335         }
336     }
337 
338     /**
339      * delete a given permission for a given id
340      * 
341      * @param permission
342      *            String type of permission like read, writedb, etc.
343      * @param id
344      *            String the id of the object the rule is assigned to
345      */
346     @MCRCommand(syntax = "delete permission {0} for id {1}",
347         help = "The command delete access rule for a given id of a given permission",
348         order = 110)
349     public static void permissionDeleteForID(String permission, String id) {
350         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
351         accessImpl.removeRule(id, permission);
352     }
353 
354     /**
355      * delete all permissions for a given id
356      * 
357      * @param id
358      *            String the id of the object the rule is assigned to
359      */
360     @MCRCommand(syntax = "delete all permissions for id {1}",
361         help = "The command delete all access rules for a given id",
362         order = 120)
363     public static void permissionDeleteAllForID(String id) {
364         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
365         accessImpl.removeAllRules(id);
366     }
367 
368     /**
369      * delete all permissions for all selected objects
370      * 
371      * @param permission
372      *            String type of permission like read, writedb, etc.
373      * @see MCRObjectCommands#getSelectedObjectIDs()
374      */
375     @MCRCommand(syntax = "delete permission {0} for selected",
376         help = "The command delete access rule for a query selected set of object ids of a given permission",
377         order = 130)
378     public static void permissionDeleteForSelected(String permission) {
379         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
380         for (String id : MCRObjectCommands.getSelectedObjectIDs()) {
381             accessImpl.removeRule(id, permission);
382         }
383     }
384 
385     /**
386      * delete all permissions for all selected objects
387      * 
388      * @see MCRObjectCommands#getSelectedObjectIDs()
389      */
390 
391     @MCRCommand(syntax = "delete all permissions for selected",
392         help = "The command delete all access rules for a query selected set of object ids",
393         order = 140)
394     public static void permissionDeleteAllForSelected() {
395         MCRRuleAccessInterface accessImpl = MCRAccessManager.requireRulesInterface();
396         for (String id : MCRObjectCommands.getSelectedObjectIDs()) {
397             accessImpl.removeAllRules(id);
398         }
399     }
400 
401     @MCRCommand(
402         syntax = "set website read only {0}",
403         help = "This command set the whole website into read only mode and provides the given message to users. "
404             + "Nobody, except super user can write on system, using web frontend. Parameter {0} specifies a message "
405             + "to be displayed",
406         order = 150)
407     public static void setWebsiteReadOnly(String message) {
408         MCRWebsiteWriteProtection.activate(message);
409     }
410 
411     @MCRCommand(
412         syntax = "set website read only",
413         help = "This command set the whole website into read only mode. "
414             + "An already configurated message will be displayed to users. "
415             + "Nobody, except super user can write on system, using web frontend",
416         order = 160)
417     public static void setWebsiteReadOnly() {
418         MCRWebsiteWriteProtection.activate();
419 
420     }
421 
422     @MCRCommand(
423         syntax = "unset website read only",
424         help = "This command removes the write protection (read only) from website. "
425             + "After unsetting anybody can write as usual, using web frontend",
426         order = 170)
427     public static void unsetWebsiteReadOnly() {
428         MCRWebsiteWriteProtection.deactivate();
429     }
430 
431 }