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;
20  
21  import java.io.File;
22  import java.io.FileOutputStream;
23  import java.io.IOException;
24  
25  import org.jdom2.Document;
26  import org.jdom2.Element;
27  import org.jdom2.JDOMException;
28  import org.jdom2.input.SAXBuilder;
29  import org.jdom2.output.DOMOutputter;
30  import org.jdom2.output.XMLOutputter;
31  import org.mycore.common.MCRSessionMgr;
32  import org.mycore.common.MCRSystemUserInformation;
33  import org.mycore.common.config.MCRConfiguration2;
34  
35  import jakarta.servlet.http.HttpServletRequest;
36  import jakarta.servlet.http.HttpServletResponse;
37  
38  public final class MCRWebsiteWriteProtection {
39      private static final String FS = System.getProperty("file.separator");
40  
41      private static final String CONFIG_FOLDER_PATH = MCRConfiguration2.getStringOrThrow("MCR.datadir") + FS
42          + "config";
43  
44      private static final String CONFIG_FILE_PATH = CONFIG_FOLDER_PATH + FS + "config-writeProtectionWebsite.xml";
45  
46      private static final File CONFIG_FILE = new File(CONFIG_FILE_PATH);
47  
48      private static long cacheInitTime = 0;
49  
50      private static Element configCache = null;
51  
52      private MCRWebsiteWriteProtection() {
53          //do not allow instantiation
54      }
55  
56      /**
57       * Checks if website protection is currently active.
58       * If current user is super user this method always returns false.
59       * 
60       * @return true if write access is currently active, false if not
61       */
62      public static boolean isActive() {
63          // if superuser is online, return false
64          String superUser = MCRSystemUserInformation.getSuperUserInstance().getUserID();
65          if (MCRSessionMgr.getCurrentSession().getUserInformation().getUserID().equals(superUser)) {
66              return false;
67          }
68          // init, if impossible return false
69          Element config = getConfiguration();
70          if (config == null) {
71              return false;
72          }
73          // return value contained in config
74          String protection = config.getChildTextTrim("protectionEnabled");
75          return Boolean.valueOf(protection);
76      }
77  
78      public static org.w3c.dom.Document getMessage() throws JDOMException, IOException {
79          Element config = getConfiguration();
80          if (config == null) {
81              return new DOMOutputter().output(new Document());
82          } else {
83              Element messageElem = config.getChild("message");
84              Document message = new Document(messageElem.clone());
85              return new DOMOutputter().output(message);
86          }
87      }
88  
89      private static Element getConfiguration() {
90          // try to get file
91          File configFolder = new File(CONFIG_FOLDER_PATH);
92          if (!configFolder.exists()) {
93              configFolder.mkdirs();
94          }
95          // file exist?, return it's content
96          if (CONFIG_FILE.exists()) {
97              Element config = null;
98              // try to get from cache
99              if (cacheValid()) {
100                 config = configCache;
101             } else {
102                 SAXBuilder builder = new SAXBuilder();
103                 try {
104                     config = builder.build(CONFIG_FILE).getRootElement();
105                     // update cache
106                     updateCache(config);
107                 } catch (JDOMException | IOException e) {
108                     e.printStackTrace();
109                     return null;
110                 }
111             }
112             return config;
113         } else {
114             // create XML
115             Element config = configToJDOM(false, " ");
116             setConfiguration(config);
117             return config;
118         }
119     }
120 
121     private static void setConfiguration(Element configXML) {
122         try {
123             // save
124             XMLOutputter xmlOut = new XMLOutputter();
125             FileOutputStream fos = new FileOutputStream(CONFIG_FILE);
126             xmlOut.output(configXML, fos);
127             fos.flush();
128             fos.close();
129         } catch (IOException e) {
130             e.printStackTrace();
131         }
132         updateCache(configXML);
133     }
134 
135     /**
136      * @param configXML
137      */
138     private static void updateCache(Element configXML) {
139         configCache = configXML;
140         cacheInitTime = System.currentTimeMillis();
141     }
142 
143     private static Element configToJDOM(boolean protection, String message) {
144         Element xml = new Element("config-writeProtectionWebsite");
145         xml.addContent(new Element("protectionEnabled").setText(Boolean.toString(protection)));
146         xml.addContent(new Element("message").setText(message));
147         return xml;
148     }
149 
150     // to be used by cli
151     public static void activate() {
152         // create file, set param in file to true, add message to file
153         Element config = getConfiguration();
154         config.getChild("protectionEnabled").setText("true");
155         setConfiguration(config);
156     }
157 
158     // to be used by cli
159     public static void activate(String message) {
160         // create file, set param in file to true, add message to file
161         Element config = getConfiguration();
162         config.getChild("protectionEnabled").setText("true");
163         config.getChild("message").setText(message);
164         setConfiguration(config);
165     }
166 
167     // to be used by cli
168     public static void deactivate() {
169         // set param in file to false
170         Element config = getConfiguration();
171         config.getChild("protectionEnabled").setText("false");
172         setConfiguration(config);
173     }
174 
175     public static boolean printInfoPageIfNoAccess(HttpServletRequest request, HttpServletResponse response,
176         String baseURL) throws IOException {
177         if (MCRWebsiteWriteProtection.isActive()) {
178             response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
179             String pageURL = baseURL + MCRConfiguration2.getStringOrThrow("MCR.WriteProtectionWebsite.ErrorPage");
180             response.sendRedirect(response.encodeRedirectURL(pageURL));
181             return true;
182         }
183         return false;
184     }
185 
186     /**
187      * Verifies if the cache of configuration is valid.
188      * 
189      * @return true if valid, false if note
190      */
191     private static boolean cacheValid() {
192         return !(configCache == null || cacheInitTime < CONFIG_FILE.lastModified());
193     }
194 
195 }