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 org.mycore.frontend.servlets;
025
026 import java.io.InputStream;
027 import java.net.URL;
028 import java.util.ArrayList;
029 import java.util.Collection;
030 import java.util.List;
031
032 import org.apache.log4j.Logger;
033 import org.jdom.Element;
034 import org.mycore.access.MCRAccessManager;
035 import org.mycore.common.MCRConfiguration;
036 import org.mycore.common.MCRConfigurationException;
037 import org.mycore.common.MCRException;
038 import org.mycore.common.MCRSession;
039 import org.mycore.common.MCRSessionMgr;
040 import org.mycore.datamodel.common.MCRActiveLinkException;
041 import org.mycore.datamodel.metadata.MCRObjectID;
042 import org.mycore.datamodel.metadata.MCRObjectService;
043 import org.mycore.frontend.editor.MCREditorSubmission;
044 import org.mycore.frontend.editor.MCRRequestParameters;
045 import org.mycore.user.MCRUserMgr;
046
047 /**
048 * The servlet store the MCREditorServlet output XML in a file of a MCR type
049 * dependencies directory, check it dependence of the MCR type and store the XML
050 * in a file in this directory or if an error was occured start the editor again
051 * with <b>todo </b> <em>repair</em>.
052 *
053 * @author Jens Kupferschmidt
054 * @author Thomas Scheffler (yagee)
055 * @version $Revision: 15202 $ $Date: 2009-05-15 17:00:44 +0200 (Fri, 15 May 2009) $
056 */
057 public class MCRCheckClassACLServlet extends MCRServlet {
058
059 private static final long serialVersionUID = 1L;
060
061 // The logger
062 protected static Logger LOGGER = Logger.getLogger(MCRCheckClassACLServlet.class);
063
064 // the configured permissions
065 private static String storedrules = MCRConfiguration.instance().getString("MCR.Access.StorePermissions", "read,write,delete");
066
067 // The User Manager
068 protected static MCRUserMgr UM = MCRUserMgr.instance();
069
070 /**
071 * This method overrides doGetPost of MCRServlet and handels all actions
072 * against the ACL data.
073 *
074 * @param job
075 * the MCRServlet job instance
076 */
077 public void doGetPost(MCRServletJob job) throws Exception {
078 // read the XML data
079 MCREditorSubmission sub = (MCREditorSubmission) (job.getRequest().getAttribute("MCREditorSubmission"));
080 org.jdom.Document indoc = sub.getXML();
081
082 // read the parameter
083 MCRRequestParameters parms;
084
085 if (sub == null) {
086 parms = new MCRRequestParameters(job.getRequest());
087 } else {
088 parms = sub.getParameters();
089 }
090
091 String oldmcrid = parms.getParameter("mcrid");
092 LOGGER.debug("XSL.target.param.0 = " + oldmcrid);
093 MCRObjectID ID = new MCRObjectID(oldmcrid);
094
095 // get the MCRSession object for the current thread from the session
096 // manager.
097 MCRSession mcrSession = MCRSessionMgr.getCurrentSession();
098 String lang = mcrSession.getCurrentLanguage();
099 LOGGER.info("LANG = " + lang);
100
101 // create a service object and prepare it
102 Element outelm = prepareService((org.jdom.Document) indoc.clone(), ID, job, lang);
103
104 // Save the prepared metadata object
105 boolean okay = storeService(outelm, job, ID);
106
107 // call the getNextURL and sendMail methods
108 String url = getNextURL(ID, okay);
109 sendMail(ID);
110
111 job.getResponse().sendRedirect(job.getResponse().encodeRedirectURL(getBaseURL() + url));
112 }
113
114 /**
115 * The method return an URL with the next working step. If okay flag is
116 * true, the object will present else it shows the error page.
117 *
118 * @param ID
119 * the MCRObjectID of the MCRObject
120 * @param okay
121 * the return value of the store operation
122 * @return the next URL as String
123 */
124 protected String getNextURL(MCRObjectID ID, boolean okay) throws MCRActiveLinkException {
125 StringBuffer sb = new StringBuffer();
126 if (okay) {
127 sb.append("browse?mode=edit");
128 } else {
129 sb.append(MCRConfiguration.instance().getString("MCR.SWF.PageDir", "")).append(MCRConfiguration.instance().getString("MCR.SWF.PageErrorStore", "editor_error_store.xml"));
130 }
131 return sb.toString();
132 }
133
134 /**
135 * The method send a message to the mail address for the MCRObjectType.
136 *
137 * @param ID
138 * the MCRObjectID of the MCRObject
139 */
140 public final void sendMail(MCRObjectID ID) {
141 LOGGER.warn("Send mail is not configured for modify ACLs");
142 }
143
144 /**
145 * The method read the incoming servacls JDOM tree in a MCRService and
146 * prepare this by the following rules. After them it return a JDOM Element
147 * of servacls as clone of the prepared data.
148 *
149 * @param jdom_in
150 * the JDOM tree from the editor
151 * @param ID
152 * the MCRObjectID of the MCRObject
153 * @param job
154 * the MCRServletJob data
155 * @param lang
156 * the current language
157 */
158 @SuppressWarnings("unchecked")
159 protected Element prepareService(org.jdom.Document jdom_in, MCRObjectID ID, MCRServletJob job, String lang) throws Exception {
160 Element elm_out = null;
161 ArrayList <String>logtext = new ArrayList<String>();
162 Element root = jdom_in.getRootElement();
163 if (root != null) {
164 Element servacls = root.getChild("servacls");
165 if (servacls != null) {
166 List<Element> servacllist = servacls.getChildren("servacl");
167 if (servacllist.size() != 0) {
168 for (int i = 0; i < servacllist.size(); i++) {
169 Element servacl = servacllist.get(i);
170 Element outcond = servacl.getChild("condition");
171 if (outcond != null) {
172 Element outbool = outcond.getChild("boolean");
173 if (outbool != null) {
174 List<Element> inbool = outbool.getChildren("boolean");
175 String outoper = outbool.getAttributeValue("operator");
176 if (inbool.size() != 0 && outoper != null && !outoper.equals("true")) {
177 for (int j = 0; j < inbool.size(); j++) {
178 List<Element> incondlist = inbool.get(j).getChildren("condition");
179 int k = incondlist.size();
180 if (k != 0) {
181 for (int l = 0; l < k; l++) {
182 Element incond = incondlist.get(l);
183 String condvalue = incond.getAttributeValue("value");
184 if (condvalue == null || (condvalue = condvalue.trim()).length() == 0) {
185 ((Element) inbool.get(j)).removeContent(incond);
186 k--;
187 l--;
188 continue;
189 }
190 String condfield = incond.getAttributeValue("field");
191 if (condfield.equals("user")) {
192 if (!UM.existUser(condvalue)) {
193 ((Element) inbool.get(j)).removeContent(incond);
194 k--;
195 l--;
196 continue;
197 }
198 }
199 if (condfield.equals("group")) {
200 if (!UM.existGroup(condvalue)) {
201 ((Element) inbool.get(j)).removeContent(incond);
202 k--;
203 l--;
204 continue;
205 }
206 }
207 }
208 if (k == 1) {
209 Element newtrue = new Element("boolean");
210 newtrue.setAttribute("operator", "true");
211 ((Element) inbool.get(j)).addContent(newtrue);
212 }
213 } else {
214 logtext.add("Can't find an inner condition element.");
215 }
216 }
217 } else {
218 if (outoper == null || !outoper.equals("true")) {
219 logtext.add("Wrong structure of MyCoRe ACL JDOM in boolean.");
220 }
221 }
222 } else {
223 outbool = new Element("boolean");
224 outbool.setAttribute("operator", "true");
225 outcond.addContent(outbool);
226 }
227 } else {
228 logtext.add("Can't find a condition element.");
229 }
230 }
231 } else {
232 logtext.add("Can't find a servacl element.");
233 }
234 } else {
235 logtext.add("Can't find the servacls element.");
236 }
237 } else {
238 logtext.add("The service part is null.");
239 }
240 elm_out = (Element) root.clone();
241 errorHandlerValid(job, logtext, ID, lang);
242 return elm_out;
243 }
244
245 /**
246 * The method store the incoming service data from the ACL editor to the
247 * workflow.
248 *
249 * @param outelm
250 * the service subelement of an MCRObject
251 * @param job
252 * the MCRServletJob instance
253 * @param ID
254 * the MCRObjectID
255 */
256 public final boolean storeService(Element outelm, MCRServletJob job, MCRObjectID ID) {
257 // check current state
258 Collection<String> li = MCRAccessManager.getPermissionsForID(ID.getId());
259 int aclsize = 0;
260 if (li != null) {
261 aclsize = li.size();
262 }
263 if (aclsize == 0) {
264 LOGGER.warn("They are no ACLs defined for classification " + ID.getId());
265 return false;
266 }
267 // check incoming ACLs
268 int rulesize = 0;
269 MCRObjectService serv = new MCRObjectService();
270 try {
271 serv.setFromDOM(outelm);
272 rulesize = serv.getRulesSize();
273 } catch (Exception e) {
274 e.printStackTrace();
275 }
276 if (rulesize == 0) {
277 LOGGER.warn("The new ACL conditions for classification" + ID.getId() + " are empty!");
278 }
279 while (0 < rulesize) {
280 Element conditions = serv.getRule(0).getCondition();
281 String permission = serv.getRule(0).getPermission();
282 if (storedrules.indexOf(permission) != -1) {
283 if (li.contains(permission)) {
284 MCRAccessManager.updateRule(ID.getId(), permission, conditions, "");
285 } else {
286 MCRAccessManager.addRule(ID.getId(), permission, conditions, "");
287 }
288 }
289 serv.removeRule(0);
290 rulesize--;
291 }
292
293 LOGGER.info("ACL of classification " + ID.getId() + " stored in the server.");
294 return true;
295 }
296
297 /**
298 * An internal method to handle validation errors.
299 *
300 * @param job
301 * the MCRServletJob instance
302 * @param logtext
303 * a list of log texts as strings
304 * @param ID
305 * the current MCRObjectID
306 * @param lang
307 * the current language
308 */
309 @SuppressWarnings("unchecked")
310 private final void errorHandlerValid(MCRServletJob job, List<String> logtext, MCRObjectID ID, String lang) throws Exception {
311 if (logtext.size() == 0) {
312 return;
313 }
314
315 // write to the log file
316 for (int i = 0; i < logtext.size(); i++) {
317 LOGGER.error(logtext.get(i));
318 }
319
320 // prepare editor with error messages
321 String pagedir = MCRConfiguration.instance().getString("MCR.editor_page_dir", "");
322 String myfile = pagedir + MCRConfiguration.instance().getString("MCR.editor_page_error_formular", "editor_error_formular.xml");
323 org.jdom.Document jdom = null;
324
325 try {
326 InputStream in = (new URL(getBaseURL() + myfile + "?XSL.Style=xml")).openStream();
327
328 if (in == null) {
329 throw new MCRConfigurationException("Can't read editor file " + myfile);
330 }
331
332 jdom = new org.jdom.input.SAXBuilder().build(in);
333
334 Element root = jdom.getRootElement();
335 List<Element> sectionlist = root.getChildren("section");
336
337 for (int i = 0; i < sectionlist.size(); i++) {
338 Element section = (Element) sectionlist.get(i);
339
340 if (!section.getAttributeValue("lang", org.jdom.Namespace.XML_NAMESPACE).equals(lang.toLowerCase())) {
341 continue;
342 }
343
344 Element p = new Element("p");
345 section.addContent(0, p);
346
347 Element center = new Element("center");
348
349 // the error message
350 Element table = new Element("table");
351 table.setAttribute("width", "80%");
352
353 for (int j = 0; j < logtext.size(); j++) {
354 Element tr = new Element("tr");
355 Element td = new Element("td");
356 Element el = new Element("font");
357 el.setAttribute("color", "red");
358 el.addContent((String) logtext.get(j));
359 td.addContent(el);
360 tr.addContent(td);
361 table.addContent(tr);
362 }
363
364 center.addContent(table);
365 section.addContent(1, center);
366 p = new Element("p");
367 section.addContent(2, p);
368
369 // the edit button
370 Element form = section.getChild("form");
371 form.setAttribute("action", job.getResponse().encodeRedirectURL(getBaseURL() + "servlets/MCRStartEditorServlet"));
372
373 Element input1 = new Element("input");
374 input1.setAttribute("name", "lang");
375 input1.setAttribute("type", "hidden");
376 input1.setAttribute("value", lang);
377 form.addContent(input1);
378
379 Element input2 = new Element("input");
380 input2.setAttribute("name", "se_mcrid");
381 input2.setAttribute("type", "hidden");
382 input2.setAttribute("value", ID.getId());
383 form.addContent(input2);
384
385 Element input3 = new Element("input");
386 input3.setAttribute("name", "type");
387 input3.setAttribute("type", "hidden");
388 input3.setAttribute("value", ID.getTypeId());
389 form.addContent(input3);
390 }
391 } catch (org.jdom.JDOMException e) {
392 throw new MCRException("Can't read editor file " + myfile + " or it has a parse error.", e);
393 }
394
395 // restart editor
396 job.getRequest().setAttribute("XSL.Style", lang);
397 getLayoutService().doLayout(job.getRequest(), job.getResponse(), jdom);
398 }
399 }