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