001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.webdav;
016    
017    import com.liferay.portal.NoSuchGroupException;
018    import com.liferay.portal.NoSuchUserException;
019    import com.liferay.portal.kernel.dao.orm.QueryUtil;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
023    import com.liferay.portal.kernel.util.CharPool;
024    import com.liferay.portal.kernel.util.FileUtil;
025    import com.liferay.portal.kernel.util.GetterUtil;
026    import com.liferay.portal.kernel.util.HttpUtil;
027    import com.liferay.portal.kernel.util.OrderByComparator;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.util.StringUtil;
030    import com.liferay.portal.kernel.util.Time;
031    import com.liferay.portal.kernel.util.UniqueList;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.kernel.xml.Namespace;
034    import com.liferay.portal.kernel.xml.SAXReaderUtil;
035    import com.liferay.portal.model.Group;
036    import com.liferay.portal.model.GroupConstants;
037    import com.liferay.portal.model.User;
038    import com.liferay.portal.service.GroupLocalServiceUtil;
039    import com.liferay.portal.service.UserLocalServiceUtil;
040    import com.liferay.portal.util.comparator.GroupFriendlyURLComparator;
041    import com.liferay.portlet.documentlibrary.util.DLUtil;
042    
043    import java.util.ArrayList;
044    import java.util.Collection;
045    import java.util.Collections;
046    import java.util.LinkedHashMap;
047    import java.util.List;
048    import java.util.Map;
049    import java.util.TreeMap;
050    
051    import javax.servlet.http.HttpServletRequest;
052    
053    /**
054     * @author Brian Wing Shun Chan
055     * @author Alexander Chow
056     * @author Raymond Aug??
057     */
058    public class WebDAVUtil {
059    
060            public static final Namespace DAV_URI = SAXReaderUtil.createNamespace(
061                    "D", "DAV:");
062    
063            public static final int SC_LOCKED = 423;
064    
065            public static final int SC_MULTI_STATUS = 207;
066    
067            public static final String TOKEN_PREFIX = "opaquelocktoken:";
068    
069            public static void addStorage(WebDAVStorage storage) {
070                    getInstance()._addStorage(storage);
071            }
072    
073            public static Namespace createNamespace(String prefix, String uri) {
074                    Namespace namespace = null;
075    
076                    if (uri.equals(WebDAVUtil.DAV_URI.getURI())) {
077                            namespace = WebDAVUtil.DAV_URI;
078                    }
079                    else if (Validator.isNull(prefix)) {
080                            namespace = SAXReaderUtil.createNamespace(uri);
081                    }
082                    else {
083                            namespace = SAXReaderUtil.createNamespace(prefix, uri);
084                    }
085    
086                    return namespace;
087            }
088    
089            public static void deleteStorage(WebDAVStorage storage) {
090                    getInstance()._deleteStorage(storage);
091            }
092    
093            public static long getDepth(HttpServletRequest request) {
094                    String value = GetterUtil.getString(request.getHeader("Depth"));
095    
096                    if (_log.isDebugEnabled()) {
097                            _log.debug("\"Depth\" header is " + value);
098                    }
099    
100                    if (value.equals("0")) {
101                            return 0;
102                    }
103                    else {
104                            return -1;
105                    }
106            }
107    
108            public static String getDestination(
109                    HttpServletRequest request, String rootPath) {
110    
111                    String headerDestination = request.getHeader("Destination");
112                    String[] pathSegments = StringUtil.split(headerDestination, rootPath);
113    
114                    String destination = pathSegments[pathSegments.length - 1];
115    
116                    destination = HttpUtil.decodePath(destination);
117    
118                    if (_log.isDebugEnabled()) {
119                            _log.debug("Destination " + destination);
120                    }
121    
122                    return destination;
123            }
124    
125            public static long getGroupId(long companyId, String path)
126                    throws WebDAVException {
127    
128                    String[] pathArray = getPathArray(path);
129    
130                    return getGroupId(companyId, pathArray);
131            }
132    
133            public static long getGroupId(long companyId, String[] pathArray)
134                    throws WebDAVException {
135    
136                    try {
137                            if (pathArray.length == 0) {
138                                    return 0;
139                            }
140    
141                            String name = pathArray[0];
142    
143                            try {
144                                    Group group = GroupLocalServiceUtil.getFriendlyURLGroup(
145                                            companyId, StringPool.SLASH + name);
146    
147                                    return group.getGroupId();
148                            }
149                            catch (NoSuchGroupException nsge) {
150                            }
151    
152                            try {
153                                    User user = UserLocalServiceUtil.getUserByScreenName(
154                                            companyId, name);
155    
156                                    Group group = user.getGroup();
157    
158                                    return group.getGroupId();
159                            }
160                            catch (NoSuchUserException nsue) {
161                            }
162                    }
163                    catch (Exception e) {
164                            throw new WebDAVException(e);
165                    }
166    
167                    return 0;
168            }
169    
170            public static List<Group> getGroups(long userId) throws Exception {
171                    User user = UserLocalServiceUtil.getUser(userId);
172    
173                    return getGroups(user);
174            }
175    
176            public static List<Group> getGroups(User user) throws Exception {
177    
178                    // Guest
179    
180                    if (user.isDefaultUser()) {
181                            List<Group> groups = new ArrayList<Group>();
182    
183                            Group group = GroupLocalServiceUtil.getGroup(
184                                    user.getCompanyId(), GroupConstants.GUEST);
185    
186                            groups.add(group);
187    
188                            return groups;
189                    }
190    
191                    // Communities
192    
193                    List<Group> groups = new UniqueList<Group>();
194    
195                    LinkedHashMap<String, Object> params =
196                            new LinkedHashMap<String, Object>();
197    
198                    params.put("usersGroups", user.getUserId());
199    
200                    OrderByComparator orderByComparator = new GroupFriendlyURLComparator(
201                            true);
202    
203                    groups.addAll(
204                            GroupLocalServiceUtil.search(
205                                    user.getCompanyId(), null, null, params, QueryUtil.ALL_POS,
206                                    QueryUtil.ALL_POS, orderByComparator));
207    
208                    // Organizations
209    
210                    groups.addAll(
211                            GroupLocalServiceUtil.getUserOrganizationsGroups(
212                                    user.getUserId(), QueryUtil.ALL_POS, QueryUtil.ALL_POS));
213    
214                    // User
215    
216                    if (!user.isDefaultUser()) {
217                            groups.add(user.getGroup());
218                    }
219    
220                    Collections.sort(groups, orderByComparator);
221    
222                    return groups;
223            }
224    
225            public static WebDAVUtil getInstance() {
226                    PortalRuntimePermission.checkGetBeanProperty(WebDAVUtil.class);
227    
228                    return _instance;
229            }
230    
231            public static String getLockUuid(HttpServletRequest request)
232                    throws WebDAVException {
233    
234                    String token = StringPool.BLANK;
235    
236                    String value = GetterUtil.getString(request.getHeader("If"));
237    
238                    if (_log.isDebugEnabled()) {
239                            _log.debug("\"If\" header is " + value);
240                    }
241    
242                    if (value.contains("(<DAV:no-lock>)")) {
243                            if (_log.isWarnEnabled()) {
244                                    _log.warn("Lock tokens can never be <DAV:no-lock>");
245                            }
246    
247                            throw new WebDAVException();
248                    }
249    
250                    int beg = value.indexOf(TOKEN_PREFIX);
251    
252                    if (beg >= 0) {
253                            beg += TOKEN_PREFIX.length();
254    
255                            if (beg < value.length()) {
256                                    int end = value.indexOf(CharPool.GREATER_THAN, beg);
257    
258                                    token = GetterUtil.getString(value.substring(beg, end));
259                            }
260                    }
261    
262                    return token;
263            }
264    
265            public static String[] getPathArray(String path) {
266                    return getPathArray(path, false);
267            }
268    
269            public static String[] getPathArray(String path, boolean fixTrailing) {
270                    path = HttpUtil.fixPath(path, true, fixTrailing);
271    
272                    return StringUtil.split(path, CharPool.SLASH);
273            }
274    
275            public static String getResourceName(String[] pathArray) {
276                    if (pathArray.length <= 2) {
277                            return StringPool.BLANK;
278                    }
279                    else {
280                            return pathArray[pathArray.length - 1];
281                    }
282            }
283    
284            public static WebDAVStorage getStorage(String token) {
285                    return getInstance()._getStorage(token);
286            }
287    
288            public static Collection<String> getStorageTokens() {
289                    return getInstance()._getStorageTokens();
290            }
291    
292            public static long getTimeout(HttpServletRequest request) {
293                    final String TIME_PREFIX = "Second-";
294    
295                    long timeout = 0;
296    
297                    String value = GetterUtil.getString(request.getHeader("Timeout"));
298    
299                    if (_log.isDebugEnabled()) {
300                            _log.debug("\"Timeout\" header is " + value);
301                    }
302    
303                    int index = value.indexOf(TIME_PREFIX);
304    
305                    if (index >= 0) {
306                            index += TIME_PREFIX.length();
307    
308                            if (index < value.length()) {
309                                    timeout = GetterUtil.getLong(value.substring(index));
310                            }
311                    }
312    
313                    return timeout * Time.SECOND;
314            }
315    
316            public static boolean isOverwrite(HttpServletRequest request) {
317                    return getInstance()._isOverwrite(request);
318            }
319    
320            public static String stripOfficeExtension(String url) {
321                    String strippedUrl = stripToken(url, DLUtil.OFFICE_EXTENSION_PATH);
322    
323                    if (strippedUrl.length() != url.length()) {
324                            strippedUrl = FileUtil.stripExtension(strippedUrl);
325                    }
326    
327                    return strippedUrl;
328            }
329    
330            public static String stripToken(String url, String token) {
331                    if (Validator.isNull(url)) {
332                            return StringPool.BLANK;
333                    }
334    
335                    int index = url.indexOf(token);
336    
337                    if (index >= 0) {
338                            url =
339                                    url.substring(0, index) + url.substring(index + token.length());
340                    }
341    
342                    return url;
343            }
344    
345            private WebDAVUtil() {
346                    _storageMap = new TreeMap<String, WebDAVStorage>();
347            }
348    
349            private void _addStorage(WebDAVStorage storage) {
350                    _storageMap.put(storage.getToken(), storage);
351            }
352    
353            private void _deleteStorage(WebDAVStorage storage) {
354                    if (storage != null) {
355                            _storageMap.remove(storage.getToken());
356                    }
357            }
358    
359            private WebDAVStorage _getStorage(String token) {
360                    return _storageMap.get(token);
361            }
362    
363            private Collection<String> _getStorageTokens() {
364                    return _storageMap.keySet();
365            }
366    
367            private boolean _isOverwrite(HttpServletRequest request) {
368                    String value = GetterUtil.getString(request.getHeader("Overwrite"));
369    
370                    if (value.equalsIgnoreCase("F") || !GetterUtil.getBoolean(value)) {
371                            return false;
372                    }
373                    else {
374                            return true;
375                    }
376            }
377    
378            private static Log _log = LogFactoryUtil.getLog(WebDAVUtil.class);
379    
380            private static WebDAVUtil _instance = new WebDAVUtil();
381    
382            private Map<String, WebDAVStorage> _storageMap;
383    
384    }