001 package org.mycore.frontend;
002
003 import java.io.File;
004 import java.io.IOException;
005 import java.util.HashMap;
006
007 import org.apache.log4j.Logger;
008 import org.jdom.Document;
009 import org.jdom.Element;
010 import org.jdom.JDOMException;
011 import org.jdom.input.SAXBuilder;
012 import org.jdom.xpath.XPath;
013 import org.mycore.access.MCRAccessInterface;
014 import org.mycore.access.MCRAccessManager;
015 import org.mycore.access.mcrimpl.MCRAccessStore;
016 import org.mycore.common.MCRConfiguration;
017 import org.mycore.common.MCRSessionMgr;
018 import org.mycore.user.MCRUser;
019
020 public class MCRLayoutUtilities {
021 final static String OBJIDPREFIX_WEBPAGE = "webpage:";
022
023 final static String READ_PERMISSION_WEBPAGE = "read";
024
025 // strategies for access verification
026 public final static int ALLTRUE = 1;
027
028 public final static int ONETRUE_ALLTRUE = 2;
029
030 public final static int ALL2BLOCKER_TRUE = 3;
031
032 private final static Logger LOGGER = Logger.getLogger(MCRLayoutUtilities.class);
033
034 private static HashMap<String, Element> itemStore = new HashMap<String, Element>();
035
036 private static long CACHE_INITTIME = 0;
037
038 private static Document NAVI;
039
040 private static final String NAV_LOC_DEFAULT = MCRConfiguration.instance().getString("MCR.basedir")
041 + "build/webapps/config/navigation.xml".replace('/', File.separatorChar);
042
043 private static final File NAVFILE = new File(MCRConfiguration.instance().getString("MCR.navigationFile", NAV_LOC_DEFAULT).replace('/',
044 File.separatorChar));
045
046 private static final boolean ACCESS_CONTROLL_ON = MCRConfiguration.instance().getBoolean("MCR.Website.ReadAccessVerification", true);
047
048 /**
049 * Verifies a given $webpage-ID (//item/@href) from navigation.xml on read
050 * permission, based on ACL-System. To be used by XSL with
051 * Xalan-Java-Extension-Call. $blockerWebpageID can be used as already
052 * verified item with read access. So, only items of the ancestor axis till
053 * and exclusive $blockerWebpageID are verified. Use this, if you want to
054 * speed up the check
055 *
056 * @param webpageID,
057 * any item/@href from navigation.xml
058 * @param blockerWebpageID,
059 * any ancestor item of webpageID from navigation.xml
060 * @return true if access granted, false if not
061 */
062 public static boolean readAccess(String webpageID, String blockerWebpageID) {
063 if (ACCESS_CONTROLL_ON) {
064 long startTime = System.currentTimeMillis();
065 boolean access = getAccess(webpageID, "read", ALL2BLOCKER_TRUE, blockerWebpageID);
066 LOGGER.debug("checked read access for webpageID= " + webpageID + " (with blockerWebpageID =" + blockerWebpageID + ") => " + access + ": took "
067 + getDuration(startTime) + " msec.");
068 return access;
069 } else
070 return true;
071 }
072
073 /**
074 * Verifies a given $webpage-ID (//item/@href) from navigation.xml on read
075 * permission, based on ACL-System. To be used by XSL with
076 * Xalan-Java-Extension-Call.
077 *
078 * @param webpageID,
079 * any item/@href from navigation.xml
080 * @return true if access granted, false if not
081 */
082 public static boolean readAccess(String webpageID) {
083 if (ACCESS_CONTROLL_ON) {
084 long startTime = System.currentTimeMillis();
085 boolean access = getAccess(webpageID, "read", ALLTRUE);
086 LOGGER.debug("checked read access for webpageID= " + webpageID + " => " + access + ": took " + getDuration(startTime) + " msec.");
087 return access;
088 } else
089 return true;
090 }
091
092 /**
093 * Returns all labels of the ancestor axis for the given item within
094 * navigation.xml
095 *
096 * @param itemClone
097 * @return Label as String, like "labelRoot > labelChild >
098 * labelChildOfChild"
099 * @throws JDOMException
100 * @throws IOException
101 */
102 public static final String getAncestorLabels(Element item) {
103 String label = "";
104 String lang = MCRSessionMgr.getCurrentSession().getCurrentLanguage().trim();
105 XPath xpath;
106 Element ic = null;
107 try {
108 xpath = XPath.newInstance("//.[@href='" + getWebpageID(item) + "']");
109 ic = (Element) xpath.selectSingleNode(getNavi());
110 } catch (JDOMException e) {
111 e.printStackTrace();
112 }
113 while (ic.getName().equals("item")) {
114 ic = ic.getParentElement();
115 String webpageID = getWebpageID(ic);
116 Element labelEl = null;
117 try {
118 xpath = XPath.newInstance("//.[@href='" + webpageID + "']/label[@xml:lang='" + lang + "']");
119 labelEl = (Element) xpath.selectSingleNode(getNavi());
120 } catch (JDOMException e) {
121 e.printStackTrace();
122 }
123 if (labelEl != null) {
124 if (label.equals(""))
125 label = labelEl.getTextTrim();
126 else
127 label = labelEl.getTextTrim() + " > " + label;
128 }
129 }
130 return label;
131 }
132
133 /**
134 * Verifies, if an item of navigation.xml has a given $permission.
135 *
136 * @param webpageID,
137 * item/@href
138 * @param permission,
139 * permission to look for
140 * @param strategy:
141 * ALLTRUE => all ancestor items of webpageID must have the
142 * permission, ONETRUE_ALLTRUE => only 1 ancestor item must have
143 * the permission
144 * @return true, if access, false if no access
145 */
146 public static boolean getAccess(String webpageID, String permission, int strategy) {
147 Element item = getItem(webpageID);
148 // check permission according to $strategy
149 boolean access = false;
150 if (strategy == ALLTRUE) {
151 access = true;
152 do {
153 access = itemAccess(permission, item, access);
154 item = item.getParentElement();
155 } while (item != null && access);
156 } else if (strategy == ONETRUE_ALLTRUE) {
157 access = false;
158 do {
159 access = itemAccess(permission, item, access);
160 item = item.getParentElement();
161 } while (item != null && !access);
162 }
163 return access;
164 }
165
166 /**
167 * Verifies, if an item of navigation.xml has a given $permission with a
168 * stop item ($blockerWebpageID)
169 *
170 * @param webpageID,
171 * item/@href
172 * @param permission,
173 * permission to look for
174 * @param strategy:
175 * ALL2BLOCKER_TRUE => all ancestor items of webpageID till and
176 * exlusiv $blockerWebpageID must have the permission
177 * @param blockerWebpageID:
178 * any ancestor item of webpageID from navigation.xml
179 * @return true, if access, false if no access
180 */
181 public static boolean getAccess(String webpageID, String permission, int strategy, String blockerWebpageID) {
182 Element item = getItem(webpageID);
183 // check permission according to $strategy
184 boolean access = false;
185 if (strategy == ALL2BLOCKER_TRUE) {
186 access = true;
187 do {
188 access = itemAccess(permission, item, access);
189 item = item.getParentElement();
190 } while (item != null && access && !getWebpageID(item).equals(blockerWebpageID));
191 }
192 return access;
193 }
194
195 /**
196 * Returns a Element presentation of an item[@href=$webpageID]
197 *
198 * @param webpageID
199 * @return Element
200 */
201 private static Element getItem(String webpageID) {
202 if (!naviCacheValid())
203 itemStore.clear();
204 Element item = itemStore.get(webpageID);
205 if (item == null) {
206 XPath xpath;
207 try {
208 xpath = XPath.newInstance("//.[@href='" + webpageID + "']");
209 item = (Element) xpath.selectSingleNode(getNavi());
210 } catch (JDOMException e) {
211 e.printStackTrace();
212 }
213 itemStore.put(webpageID, item);
214 }
215 return item;
216 }
217
218 /**
219 * Verifies a single item on access according to $permission
220 *
221 * @param permission
222 * @param item
223 * @param access,
224 * initial value
225 * @return
226 */
227 public static boolean itemAccess(String permission, Element item, boolean access) {
228 String objID = getWebpageACLID(item);
229 if (MCRAccessManager.hasRule(objID, permission))
230 access = MCRAccessManager.checkPermission(objID, permission);
231 return access;
232 }
233
234 /**
235 * Verifies a single item on access according to $permission and for a given
236 * user
237 *
238 * @param permission
239 * @param item
240 * @param access,
241 * initial value
242 * @param user
243 * @return
244 */
245 public static boolean itemAccess(String permission, Element item, boolean access, MCRUser user) {
246 MCRAccessInterface am = MCRAccessManager.getAccessImpl();
247 String objID = getWebpageACLID(item);
248 if (am.hasRule(objID, permission))
249 access = am.checkPermission(objID, permission, user);
250 return access;
251 }
252
253 /**
254 * Verifies if the cache of navigation.xml is valid.
255 *
256 * @return true if valid, false if note
257 */
258 private static boolean naviCacheValid() {
259 if (CACHE_INITTIME < NAVFILE.lastModified())
260 return false;
261 else
262 return true;
263 }
264
265 private static String getWebpageACLID(Element item) {
266 return OBJIDPREFIX_WEBPAGE + getWebpageID(item);
267 }
268
269 public static String getWebpageACLID(String webpageID) {
270 return OBJIDPREFIX_WEBPAGE + webpageID;
271 }
272
273 private static String getWebpageID(Element item) {
274 return item.getAttributeValue("href");
275 }
276
277 /**
278 * Returns the navigation.xml as org.jdom.document, using a cache the
279 * enhance loading time.
280 *
281 * @return navigation.xml as org.jdom.document
282 */
283 public static Document getNavi() {
284 if (!naviCacheValid()) {
285 try {
286 NAVI = new SAXBuilder().build(NAVFILE);
287 } catch (JDOMException e) {
288 e.printStackTrace();
289 } catch (IOException e) {
290 e.printStackTrace();
291 }
292 CACHE_INITTIME = System.currentTimeMillis();
293 }
294 return NAVI;
295 }
296
297 public static long getDuration(long startTime) {
298 return (System.currentTimeMillis() - startTime);
299 }
300
301 public static String getOBJIDPREFIX_WEBPAGE() {
302 return OBJIDPREFIX_WEBPAGE;
303 }
304
305 public static boolean hasRule(String permission, String webpageID) {
306 MCRAccessInterface am = MCRAccessManager.getAccessImpl();
307 return am.hasRule(getWebpageACLID(webpageID), permission);
308 }
309
310 public static String getRuleID(String permission, String webpageID) {
311 MCRAccessStore as = MCRAccessStore.getInstance();
312 String ruleID = as.getRuleID(getWebpageACLID(webpageID), permission);
313 if (ruleID != null)
314 return ruleID;
315 else
316 return "";
317 }
318
319 public static String getRuleDescr(String permission, String webpageID) {
320 MCRAccessInterface am = MCRAccessManager.getAccessImpl();
321 String ruleDes = am.getRuleDescription(getWebpageACLID(webpageID), permission);
322 if (ruleDes != null)
323 return ruleDes;
324 else
325 return "";
326 }
327
328 public static String getPermission2ReadWebpage() {
329 return READ_PERMISSION_WEBPAGE;
330 }
331
332 public static String getLastValidPageID() {
333 String page = (String) MCRSessionMgr.getCurrentSession().get("lastPageID");
334 return (page == null ? "" : page);
335 }
336
337 public static String setLastValidPageID(String pageID) {
338 MCRSessionMgr.getCurrentSession().put("lastPageID", pageID);
339 return "";
340 }
341 }