1   /**
2    * Copyright (c) 2000-2009 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   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.webdav;
21  
22  import com.liferay.portal.NoSuchGroupException;
23  import com.liferay.portal.kernel.configuration.Filter;
24  import com.liferay.portal.kernel.log.Log;
25  import com.liferay.portal.kernel.log.LogFactoryUtil;
26  import com.liferay.portal.kernel.util.GetterUtil;
27  import com.liferay.portal.kernel.util.HttpUtil;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.kernel.util.Time;
31  import com.liferay.portal.kernel.util.Validator;
32  import com.liferay.portal.kernel.xml.Namespace;
33  import com.liferay.portal.kernel.xml.SAXReaderUtil;
34  import com.liferay.portal.model.Company;
35  import com.liferay.portal.model.Group;
36  import com.liferay.portal.model.User;
37  import com.liferay.portal.service.CompanyLocalServiceUtil;
38  import com.liferay.portal.service.GroupLocalServiceUtil;
39  import com.liferay.portal.service.UserLocalServiceUtil;
40  import com.liferay.portal.util.PropsKeys;
41  import com.liferay.portal.util.PropsUtil;
42  
43  import java.util.Collection;
44  import java.util.HashMap;
45  import java.util.HashSet;
46  import java.util.Map;
47  import java.util.Set;
48  
49  import javax.servlet.http.HttpServletRequest;
50  
51  /**
52   * <a href="WebDAVUtil.java.html"><b><i>View Source</i></b></a>
53   *
54   * @author Brian Wing Shun Chan
55   * @author Alexander Chow
56   *
57   */
58  public class WebDAVUtil {
59  
60      public static final Namespace DAV_URI = SAXReaderUtil.createNamespace(
61          "D", "DAV:");
62  
63      public static final int SC_MULTI_STATUS = 207;
64  
65      public static final int SC_LOCKED = 423;
66  
67      public static final String TOKEN_PREFIX = "opaquelocktoken:";
68  
69      public static String encodeURL(String url) {
70          url = HttpUtil.encodeURL(url);
71          url = StringUtil.replace(url, StringPool.PLUS, StringPool.SPACE);
72  
73          return url;
74      }
75  
76      public static String fixPath(String path) {
77          if (path.endsWith(StringPool.SLASH)) {
78              path = path.substring(0, path.length() - 1);
79          }
80  
81          return path;
82      }
83  
84      public static long getCompanyId(String path) throws WebDAVException {
85          String[] pathArray = getPathArray(path);
86  
87          return getCompanyId(pathArray);
88      }
89  
90      public static long getCompanyId(String[] pathArray) throws WebDAVException {
91          try {
92              String webId = getWebId(pathArray);
93  
94              Company company = CompanyLocalServiceUtil.getCompanyByWebId(webId);
95  
96              return company.getCompanyId();
97          }
98          catch (Exception e) {
99              throw new WebDAVException(e);
100         }
101     }
102 
103     public static long getDepth(HttpServletRequest request) {
104         String value = GetterUtil.getString(request.getHeader("Depth"));
105 
106         if (_log.isDebugEnabled()) {
107             _log.debug("\"Depth\" header is " + value);
108         }
109 
110         if (value.equals("0")) {
111             return 0;
112         }
113         else {
114             return -1;
115         }
116     }
117 
118     public static String getDestination(
119         HttpServletRequest request, String rootPath) {
120 
121         String headerDestination = request.getHeader("Destination");
122         String[] pathSegments = StringUtil.split(headerDestination, rootPath);
123 
124         String destination = pathSegments[pathSegments.length - 1];
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 Log _log = LogFactoryUtil.getLog(WebDAVUtil.class);
382 
383     private static WebDAVUtil _instance = new WebDAVUtil();
384 
385     private final Set<String> _storageEditUrls;
386 
387     private final Set<String> _storageViewUrls;
388 
389     private final Map<String, String> _storageMap;
390 
391 }