001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.CookieNotSupportedException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    
021    import java.util.Collections;
022    import java.util.HashMap;
023    import java.util.Map;
024    
025    import javax.servlet.http.Cookie;
026    import javax.servlet.http.HttpServletRequest;
027    import javax.servlet.http.HttpServletResponse;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     * @author Minhchau Dang
032     */
033    public class CookieKeys {
034    
035            public static final String COMPANY_ID = "COMPANY_ID";
036    
037            public static final String COOKIE_SUPPORT = "COOKIE_SUPPORT";
038    
039            public static final String GUEST_LANGUAGE_ID = "GUEST_LANGUAGE_ID";
040    
041            public static final String ID = "ID";
042    
043            public static final String JSESSIONID = "JSESSIONID";
044    
045            public static final String LOGIN = "LOGIN";
046    
047            public static final int MAX_AGE = (int)Time.YEAR;
048    
049            /**
050             * @deprecated As of 7.0.0, replaced by {@link #MAX_AGE}
051             */
052            public static final int MAX_AGE_IN_SECONDS = (int)(Time.YEAR / 1000);
053    
054            public static final String PASSWORD = "PASSWORD";
055    
056            public static final String REMEMBER_ME = "REMEMBER_ME";
057    
058            public static final String REMOTE_PREFERENCE_PREFIX = "REMOTE_PREFERENCE_";
059    
060            public static final String SCREEN_NAME = "SCREEN_NAME";
061    
062            public static final String USER_UUID = "USER_UUID";
063    
064            public static void addCookie(
065                    HttpServletRequest request, HttpServletResponse response,
066                    Cookie cookie) {
067    
068                    addCookie(request, response, cookie, request.isSecure());
069            }
070    
071            public static void addCookie(
072                    HttpServletRequest request, HttpServletResponse response, Cookie cookie,
073                    boolean secure) {
074    
075                    if (!_SESSION_ENABLE_PERSISTENT_COOKIES || _TCK_URL) {
076                            return;
077                    }
078    
079                    // LEP-5175
080    
081                    String name = cookie.getName();
082    
083                    String originalValue = cookie.getValue();
084                    String encodedValue = originalValue;
085    
086                    if (isEncodedCookie(name)) {
087                            encodedValue = UnicodeFormatter.bytesToHex(
088                                    originalValue.getBytes());
089    
090                            if (_log.isDebugEnabled()) {
091                                    _log.debug("Add encoded cookie " + name);
092                                    _log.debug("Original value " + originalValue);
093                                    _log.debug("Hex encoded value " + encodedValue);
094                            }
095                    }
096    
097                    cookie.setSecure(secure);
098                    cookie.setValue(encodedValue);
099                    cookie.setVersion(0);
100    
101                    // Setting a cookie will cause the TCK to lose its ability to track
102                    // sessions
103    
104                    response.addCookie(cookie);
105            }
106    
107            public static void addSupportCookie(
108                    HttpServletRequest request, HttpServletResponse response) {
109    
110                    Cookie cookieSupportCookie = new Cookie(COOKIE_SUPPORT, "true");
111    
112                    cookieSupportCookie.setPath(StringPool.SLASH);
113                    cookieSupportCookie.setMaxAge(MAX_AGE_IN_SECONDS);
114    
115                    addCookie(request, response, cookieSupportCookie);
116            }
117    
118            public static String getCookie(HttpServletRequest request, String name) {
119                    return getCookie(request, name, true);
120            }
121    
122            public static String getCookie(
123                    HttpServletRequest request, String name, boolean toUpperCase) {
124    
125                    if (!_SESSION_ENABLE_PERSISTENT_COOKIES) {
126                            return null;
127                    }
128    
129                    String value = _get(request, name, toUpperCase);
130    
131                    if ((value == null) || !isEncodedCookie(name)) {
132                            return value;
133                    }
134    
135                    try {
136                            String encodedValue = value;
137                            String originalValue = new String(
138                                    UnicodeFormatter.hexToBytes(encodedValue));
139    
140                            if (_log.isDebugEnabled()) {
141                                    _log.debug("Get encoded cookie " + name);
142                                    _log.debug("Hex encoded value " + encodedValue);
143                                    _log.debug("Original value " + originalValue);
144                            }
145    
146                            return originalValue;
147                    }
148                    catch (Exception e) {
149                            if (_log.isWarnEnabled()) {
150                                    _log.warn(e.getMessage());
151                            }
152    
153                            return value;
154                    }
155            }
156    
157            public static String getDomain(HttpServletRequest request) {
158    
159                    // See LEP-4602 and       LEP-4618.
160    
161                    if (Validator.isNotNull(_SESSION_COOKIE_DOMAIN)) {
162                            return _SESSION_COOKIE_DOMAIN;
163                    }
164    
165                    String host = request.getServerName();
166    
167                    if (_SESSION_COOKIE_USE_FULL_HOSTNAME) {
168                            return StringPool.BLANK;
169                    }
170    
171                    return getDomain(host);
172            }
173    
174            public static String getDomain(String host) {
175    
176                    // See LEP-4602 and LEP-4645.
177    
178                    if (host == null) {
179                            return null;
180                    }
181    
182                    // See LEP-5595.
183    
184                    if (Validator.isIPAddress(host)) {
185                            return host;
186                    }
187    
188                    int x = host.lastIndexOf(CharPool.PERIOD);
189    
190                    if (x <= 0) {
191                            return null;
192                    }
193    
194                    int y = host.lastIndexOf(CharPool.PERIOD, x - 1);
195    
196                    if (y <= 0) {
197                            return StringPool.PERIOD + host;
198                    }
199    
200                    int z = host.lastIndexOf(CharPool.PERIOD, y - 1);
201    
202                    String domain = null;
203    
204                    if (z <= 0) {
205                            domain = host.substring(y);
206                    }
207                    else {
208                            domain = host.substring(z);
209                    }
210    
211                    return domain;
212            }
213    
214            public static boolean hasSessionId(HttpServletRequest request) {
215                    String jsessionid = getCookie(request, JSESSIONID, false);
216    
217                    if (jsessionid != null) {
218                            return true;
219                    }
220                    else {
221                            return false;
222                    }
223            }
224    
225            public static boolean isEncodedCookie(String name) {
226                    if (name.equals(ID) || name.equals(LOGIN) || name.equals(PASSWORD) ||
227                            name.equals(SCREEN_NAME) || name.equals(USER_UUID)) {
228    
229                            return true;
230                    }
231                    else {
232                            return false;
233                    }
234            }
235    
236            public static void validateSupportCookie(HttpServletRequest request)
237                    throws CookieNotSupportedException {
238    
239                    if (_SESSION_ENABLE_PERSISTENT_COOKIES &&
240                            _SESSION_TEST_COOKIE_SUPPORT) {
241    
242                            String cookieSupport = getCookie(request, COOKIE_SUPPORT, false);
243    
244                            if (Validator.isNull(cookieSupport)) {
245                                    throw new CookieNotSupportedException();
246                            }
247                    }
248            }
249    
250            private static String _get(
251                    HttpServletRequest request, String name, boolean toUpperCase) {
252    
253                    Map<String, Cookie> cookieMap = _getCookieMap(request);
254    
255                    if (toUpperCase) {
256                            name = StringUtil.toUpperCase(name);
257                    }
258    
259                    Cookie cookie = cookieMap.get(name);
260    
261                    if (cookie == null) {
262                            return null;
263                    }
264                    else {
265                            return cookie.getValue();
266                    }
267            }
268    
269            private static Map<String, Cookie> _getCookieMap(
270                    HttpServletRequest request) {
271    
272                    Map<String, Cookie> cookieMap =
273                            (Map<String, Cookie>)request.getAttribute(
274                                    CookieKeys.class.getName());
275    
276                    if (cookieMap != null) {
277                            return cookieMap;
278                    }
279    
280                    Cookie[] cookies = request.getCookies();
281    
282                    if (cookies == null) {
283                            cookieMap = Collections.emptyMap();
284                    }
285                    else {
286                            cookieMap = new HashMap<String, Cookie>(cookies.length * 4 / 3);
287    
288                            for (Cookie cookie : cookies) {
289                                    String cookieName = GetterUtil.getString(cookie.getName());
290    
291                                    cookieName = StringUtil.toUpperCase(cookieName);
292    
293                                    cookieMap.put(cookieName, cookie);
294                            }
295                    }
296    
297                    request.setAttribute(CookieKeys.class.getName(), cookieMap);
298    
299                    return cookieMap;
300            }
301    
302            private static final String _SESSION_COOKIE_DOMAIN = PropsUtil.get(
303                    PropsKeys.SESSION_COOKIE_DOMAIN);
304    
305            private static final boolean _SESSION_COOKIE_USE_FULL_HOSTNAME =
306                    GetterUtil.getBoolean(
307                            PropsUtil.get(PropsKeys.SESSION_COOKIE_USE_FULL_HOSTNAME));
308    
309            private static final boolean _SESSION_ENABLE_PERSISTENT_COOKIES =
310                    GetterUtil.getBoolean(
311                            PropsUtil.get(PropsKeys.SESSION_ENABLE_PERSISTENT_COOKIES));
312    
313            private static final boolean _SESSION_TEST_COOKIE_SUPPORT =
314                    GetterUtil.getBoolean(
315                            PropsUtil.get(PropsKeys.SESSION_TEST_COOKIE_SUPPORT));
316    
317            private static final boolean _TCK_URL = GetterUtil.getBoolean(
318                    PropsUtil.get(PropsKeys.TCK_URL));
319    
320            private static Log _log = LogFactoryUtil.getLog(CookieKeys.class);
321    
322    }