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