1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.portal.webdav;
16  
17  import com.liferay.portal.NoSuchGroupException;
18  import com.liferay.portal.kernel.configuration.Filter;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  import com.liferay.portal.kernel.util.GetterUtil;
22  import com.liferay.portal.kernel.util.HttpUtil;
23  import com.liferay.portal.kernel.util.PropsKeys;
24  import com.liferay.portal.kernel.util.StringPool;
25  import com.liferay.portal.kernel.util.StringUtil;
26  import com.liferay.portal.kernel.util.Time;
27  import com.liferay.portal.kernel.util.Validator;
28  import com.liferay.portal.kernel.xml.Namespace;
29  import com.liferay.portal.kernel.xml.SAXReaderUtil;
30  import com.liferay.portal.model.Company;
31  import com.liferay.portal.model.Group;
32  import com.liferay.portal.model.User;
33  import com.liferay.portal.service.CompanyLocalServiceUtil;
34  import com.liferay.portal.service.GroupLocalServiceUtil;
35  import com.liferay.portal.service.UserLocalServiceUtil;
36  import com.liferay.portal.util.PropsUtil;
37  
38  import java.util.Collection;
39  import java.util.HashMap;
40  import java.util.HashSet;
41  import java.util.Map;
42  import java.util.Set;
43  
44  import javax.servlet.http.HttpServletRequest;
45  
46  /**
47   * <a href="WebDAVUtil.java.html"><b><i>View Source</i></b></a>
48   *
49   * @author Brian Wing Shun Chan
50   * @author Alexander Chow
51   */
52  public class WebDAVUtil {
53  
54      public static final Namespace DAV_URI = SAXReaderUtil.createNamespace(
55          "D", "DAV:");
56  
57      public static final int SC_MULTI_STATUS = 207;
58  
59      public static final int SC_LOCKED = 423;
60  
61      public static final String TOKEN_PREFIX = "opaquelocktoken:";
62  
63      public static String encodeURL(String url) {
64          url = HttpUtil.encodeURL(url);
65          url = StringUtil.replace(url, StringPool.PLUS, StringPool.SPACE);
66  
67          return url;
68      }
69  
70      public static String fixPath(String path) {
71          if (path.endsWith(StringPool.SLASH)) {
72              path = path.substring(0, path.length() - 1);
73          }
74  
75          return path;
76      }
77  
78      public static long getCompanyId(String path) throws WebDAVException {
79          String[] pathArray = getPathArray(path);
80  
81          return getCompanyId(pathArray);
82      }
83  
84      public static long getCompanyId(String[] pathArray) throws WebDAVException {
85          try {
86              String webId = getWebId(pathArray);
87  
88              Company company = CompanyLocalServiceUtil.getCompanyByWebId(webId);
89  
90              return company.getCompanyId();
91          }
92          catch (Exception e) {
93              throw new WebDAVException(e);
94          }
95      }
96  
97      public static long getDepth(HttpServletRequest request) {
98          String value = GetterUtil.getString(request.getHeader("Depth"));
99  
100         if (_log.isDebugEnabled()) {
101             _log.debug("\"Depth\" header is " + value);
102         }
103 
104         if (value.equals("0")) {
105             return 0;
106         }
107         else {
108             return -1;
109         }
110     }
111 
112     public static String getDestination(
113         HttpServletRequest request, String rootPath) {
114 
115         String headerDestination = request.getHeader("Destination");
116         String[] pathSegments = StringUtil.split(headerDestination, rootPath);
117 
118         String destination = pathSegments[pathSegments.length - 1];
119 
120         destination =  StringUtil.replace(
121             destination, StringPool.SLASH, _TEMP_SLASH);
122         destination = HttpUtil.decodeURL(destination, true);
123         destination =  StringUtil.replace(
124             destination, _TEMP_SLASH, StringPool.SLASH);
125 
126         if (_log.isDebugEnabled()) {
127             _log.debug("Destination " + destination);
128         }
129 
130         return destination;
131     }
132 
133     public static long getGroupId(String path) throws WebDAVException {
134         String[] pathArray = getPathArray(path);
135 
136         return getGroupId(pathArray);
137     }
138 
139     public static long getGroupId(String[] pathArray) throws WebDAVException {
140         try {
141             if (pathArray.length <= 1) {
142                 return 0;
143             }
144 
145             long companyId = getCompanyId(pathArray);
146 
147             String name = pathArray[1];
148 
149             try {
150                 Group group = GroupLocalServiceUtil.getGroup(companyId, name);
151 
152                 return group.getGroupId();
153             }
154             catch (NoSuchGroupException nsge) {
155             }
156 
157             try {
158                 Group group = GroupLocalServiceUtil.getFriendlyURLGroup(
159                     companyId, StringPool.SLASH + name);
160 
161                 return group.getGroupId();
162             }
163             catch (NoSuchGroupException nsge) {
164             }
165 
166             User user = UserLocalServiceUtil.getUserByScreenName(
167                 companyId, name);
168 
169             Group group = user.getGroup();
170 
171             return group.getGroupId();
172         }
173         catch (Exception e) {
174             throw new WebDAVException(e);
175         }
176     }
177 
178     public static String getLockUuid(HttpServletRequest request)
179         throws WebDAVException {
180 
181         String token = StringPool.BLANK;
182 
183         String value = GetterUtil.getString(request.getHeader("If"));
184 
185         if (_log.isDebugEnabled()) {
186             _log.debug("\"If\" header is " + value);
187         }
188 
189         if (value.contains("(<DAV:no-lock>)")) {
190             if (_log.isWarnEnabled()) {
191                 _log.warn("Lock tokens can never be <DAV:no-lock>");
192             }
193 
194             throw new WebDAVException();
195         }
196 
197         int beg = value.indexOf(TOKEN_PREFIX);
198 
199         if (beg >= 0) {
200             beg += TOKEN_PREFIX.length();
201 
202             if (beg < value.length()) {
203                 int end = value.indexOf(">", beg);
204 
205                 token = GetterUtil.getString(value.substring(beg, end));
206             }
207         }
208 
209         return token;
210     }
211 
212     public static String[] getPathArray(String path) {
213         return getPathArray(path, false);
214     }
215 
216     public static String[] getPathArray(String path, boolean fixPath) {
217         if (fixPath) {
218             path = fixPath(path);
219         }
220 
221         if (path.startsWith(StringPool.SLASH)) {
222             path = path.substring(1, path.length());
223         }
224 
225         return StringUtil.split(path, StringPool.SLASH);
226     }
227 
228     public static String getResourceName(String[] pathArray) {
229         if (pathArray.length <= 3) {
230             return StringPool.BLANK;
231         }
232         else {
233             return pathArray[pathArray.length - 1];
234         }
235     }
236 
237     public static String getStorageClass(String token) {
238         return _instance._getStorageClass(token);
239     }
240 
241     public static String getStorageToken(String className) {
242         return _instance._getStorageToken(className);
243     }
244 
245     public static Collection<String> getStorageTokens() {
246         return _instance._getStorageTokens();
247     }
248 
249     public static long getTimeout(HttpServletRequest request) {
250         final String TIME_PREFIX = "Second-";
251 
252         long timeout = 0;
253 
254         String value = GetterUtil.getString(request.getHeader("Timeout"));
255 
256         if (_log.isDebugEnabled()) {
257             _log.debug("\"Timeout\" header is " + value);
258         }
259 
260         int index = value.indexOf(TIME_PREFIX);
261 
262         if (index >= 0) {
263             index += TIME_PREFIX.length();
264 
265             if (index < value.length()) {
266                 timeout = GetterUtil.getLong(value.substring(index));
267             }
268         }
269 
270         return timeout * Time.SECOND;
271     }
272 
273     public static String getWebId(String path) throws WebDAVException {
274         String[] pathArray = getPathArray(path);
275 
276         return getWebId(pathArray);
277     }
278 
279     public static String getWebId(String[] pathArray) throws WebDAVException {
280         if (pathArray.length > 0) {
281             String webId = pathArray[0];
282 
283             return webId;
284         }
285         else {
286             throw new WebDAVException();
287         }
288     }
289 
290     public static boolean isEditEnabled(String className) {
291         return _instance._isEditEnabled(className);
292     }
293 
294     public static boolean isEnabled(String className) {
295         return _instance._isEnabled(className);
296     }
297 
298     public static boolean isOverwrite(HttpServletRequest request) {
299         return _instance._isOverwrite(request);
300     }
301 
302     public static boolean isViewEnabled(String className) {
303         return _instance._isViewEnabled(className);
304     }
305 
306     private WebDAVUtil() {
307         _storageMap = new HashMap<String, String>();
308         _storageEditUrls = new HashSet<String>();
309         _storageViewUrls = new HashSet<String>();
310 
311         String[] tokens = PropsUtil.getArray(PropsKeys.WEBDAV_STORAGE_TOKENS);
312 
313         for (String token: tokens) {
314             Filter filter = new Filter(token);
315 
316             String className = PropsUtil.get(
317                 PropsKeys.WEBDAV_STORAGE_CLASS, filter);
318 
319             if (Validator.isNotNull(className)) {
320                 _storageMap.put(className, token);
321 
322                 boolean editUrl = GetterUtil.getBoolean(PropsUtil.get(
323                     PropsKeys.WEBDAV_STORAGE_SHOW_EDIT_URL, filter));
324                 boolean viewUrl = GetterUtil.getBoolean(PropsUtil.get(
325                     PropsKeys.WEBDAV_STORAGE_SHOW_VIEW_URL, filter));
326 
327                 if (editUrl) {
328                     _storageEditUrls.add(className);
329                 }
330 
331                 if (viewUrl) {
332                     _storageViewUrls.add(className);
333                 }
334             }
335         }
336     }
337 
338     private String _getStorageClass(String token) {
339         if (_storageMap.containsValue(token)) {
340             for (String key : _storageMap.keySet()) {
341                 if (_storageMap.get(key).equals(token)) {
342                     return key;
343                 }
344             }
345         }
346 
347         return null;
348     }
349 
350     private String _getStorageToken(String className) {
351         return _storageMap.get(className);
352     }
353 
354     private Collection<String> _getStorageTokens() {
355         return _storageMap.values();
356     }
357 
358     private boolean _isEditEnabled(String className) {
359         return _isEnabled(className) && _storageEditUrls.contains(className);
360     }
361 
362     private boolean _isEnabled(String className) {
363         return _storageMap.containsKey(className);
364     }
365 
366     private boolean _isOverwrite(HttpServletRequest request) {
367         String value = GetterUtil.getString(request.getHeader("Overwrite"));
368 
369         if (value.equalsIgnoreCase("F") || !GetterUtil.getBoolean(value)) {
370             return false;
371         }
372         else {
373             return true;
374         }
375     }
376 
377     private boolean _isViewEnabled(String className) {
378         return _isEnabled(className) && _storageViewUrls.contains(className);
379     }
380 
381     private static final String _TEMP_SLASH = "_LIFERAY_TEMP_SLASH_";
382 
383     private static Log _log = LogFactoryUtil.getLog(WebDAVUtil.class);
384 
385     private static WebDAVUtil _instance = new WebDAVUtil();
386 
387     private Set<String> _storageEditUrls;
388     private Set<String> _storageViewUrls;
389     private Map<String, String> _storageMap;
390 
391 }