View Javadoc
1   /*
2    * Copyright 2012-2021 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.helper;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.UUID;
22  
23  import javax.servlet.http.Cookie;
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.http.HttpSession;
26  
27  import org.codelibs.core.collection.LruHashMap;
28  import org.codelibs.core.lang.StringUtil;
29  import org.codelibs.fess.Constants;
30  import org.codelibs.fess.mylasta.direction.FessConfig;
31  import org.codelibs.fess.util.ComponentUtil;
32  import org.lastaflute.core.security.PrimaryCipher;
33  import org.lastaflute.web.login.TypicalUserBean;
34  import org.lastaflute.web.servlet.session.SessionManager;
35  import org.lastaflute.web.util.LaRequestUtil;
36  import org.lastaflute.web.util.LaResponseUtil;
37  
38  public class UserInfoHelper {
39      protected static final String USER_BEAN = "lastaflute.action.USER_BEAN.FessUserBean";
40  
41      protected int resultDocIdsCacheSize = 20;
42  
43      protected String cookieName = "fsid";
44  
45      protected String cookieDomain;
46  
47      protected int cookieMaxAge = 30 * 24 * 60 * 60;// 1 month
48  
49      protected String cookiePath = "/";
50  
51      protected Boolean cookieSecure;
52  
53      protected boolean httpOnly = true;
54  
55      public String getUserCode() {
56          final HttpServletRequest request = LaRequestUtil.getRequest();
57  
58          String userCode = (String) request.getAttribute(Constants.USER_CODE);
59          if (StringUtil.isNotBlank(userCode)) {
60              return userCode;
61          }
62  
63          userCode = getUserCodeFromRequest(request);
64          if (StringUtil.isNotBlank(userCode)) {
65              return userCode;
66          }
67  
68          if (!request.isRequestedSessionIdValid()) {
69              return null;
70          }
71  
72          userCode = getUserCodeFromCookie(request);
73          if (StringUtil.isBlank(userCode)) {
74              userCode = getUserCodeFromUserBean(request);
75              if (StringUtil.isBlank(userCode)) {
76                  userCode = getId();
77              }
78          }
79  
80          if (StringUtil.isNotBlank(userCode)) {
81              updateUserSessionId(userCode);
82          }
83          return userCode;
84      }
85  
86      protected String getUserCodeFromUserBean(final HttpServletRequest request) {
87          final SessionManager sessionManager = ComponentUtil.getComponent(SessionManager.class);
88          String userCode = sessionManager.getAttribute(USER_BEAN, TypicalUserBean.class)
89                  .filter(u -> !Constants.EMPTY_USER_ID.equals(u.getUserId())).map(u -> u.getUserId().toString()).orElse(StringUtil.EMPTY);
90          if (StringUtil.isBlank(userCode)) {
91              return null;
92          }
93  
94          userCode = createUserCodeFromUserId(userCode);
95          request.setAttribute(Constants.USER_CODE, userCode);
96          deleteUserCodeFromCookie(request);
97          return userCode;
98      }
99  
100     protected String createUserCodeFromUserId(String userCode) {
101         final FessConfig fessConfig = ComponentUtil.getFessConfig();
102         final PrimaryCipher cipher = ComponentUtil.getPrimaryCipher();
103         userCode = cipher.encrypt(userCode);
104         if (fessConfig.isValidUserCode(userCode)) {
105             return userCode;
106         }
107         return null;
108     }
109 
110     public void deleteUserCodeFromCookie(final HttpServletRequest request) {
111         final String cookieValue = getUserCodeFromCookie(request);
112         if (cookieValue != null) {
113             updateCookie(StringUtil.EMPTY, 0);
114         }
115     }
116 
117     protected String getUserCodeFromRequest(final HttpServletRequest request) {
118         final FessConfig fessConfig = ComponentUtil.getFessConfig();
119         final String userCode = request.getParameter(fessConfig.getUserCodeRequestParameter());
120         if (StringUtil.isBlank(userCode)) {
121             return null;
122         }
123 
124         if (fessConfig.isValidUserCode(userCode)) {
125             request.setAttribute(Constants.USER_CODE, userCode);
126             return userCode;
127         }
128         return null;
129     }
130 
131     protected String getId() {
132         return UUID.randomUUID().toString().replace("-", StringUtil.EMPTY);
133     }
134 
135     protected void updateUserSessionId(final String userCode) {
136         ComponentUtil.getSearchLogHelper().getUserInfo(userCode);
137 
138         final HttpServletRequest request = LaRequestUtil.getRequest();
139         request.setAttribute(Constants.USER_CODE, userCode);
140 
141         updateCookie(userCode, cookieMaxAge);
142     }
143 
144     protected void updateCookie(final String userCode, final int age) {
145         final Cookie cookie = new Cookie(cookieName, userCode);
146         cookie.setMaxAge(age);
147         cookie.setHttpOnly(httpOnly);
148         if (StringUtil.isNotBlank(cookieDomain)) {
149             cookie.setDomain(cookieDomain);
150         }
151         if (StringUtil.isNotBlank(cookiePath)) {
152             cookie.setPath(cookiePath);
153         }
154         if (cookieSecure != null) {
155             cookie.setSecure(cookieSecure);
156         }
157         LaResponseUtil.getResponse().addCookie(cookie);
158     }
159 
160     protected String getUserCodeFromCookie(final HttpServletRequest request) {
161         final FessConfig fessConfig = ComponentUtil.getFessConfig();
162         final Cookie[] cookies = request.getCookies();
163         if (cookies != null) {
164             for (final Cookie cookie : cookies) {
165                 if (cookieName.equals(cookie.getName()) && fessConfig.isValidUserCode(cookie.getValue())) {
166                     return cookie.getValue();
167                 }
168             }
169         }
170         return null;
171     }
172 
173     public void storeQueryId(final String queryId, final List<Map<String, Object>> documentItems) {
174         final HttpSession session = LaRequestUtil.getRequest().getSession(false);
175         if (session != null) {
176             final FessConfig fessConfig = ComponentUtil.getFessConfig();
177 
178             final List<String> docIdList = new ArrayList<>();
179             for (final Map<String, Object> map : documentItems) {
180                 final Object docId = map.get(fessConfig.getIndexFieldDocId());
181                 if (docId != null && docId.toString().length() > 0) {
182                     docIdList.add(docId.toString());
183                 }
184             }
185 
186             if (!docIdList.isEmpty()) {
187                 final Map<String, String[]> resultDocIdsCache = getResultDocIdsCache(session);
188                 resultDocIdsCache.put(queryId, docIdList.toArray(new String[docIdList.size()]));
189             }
190         }
191     }
192 
193     public String[] getResultDocIds(final String queryId) {
194         final HttpSession session = LaRequestUtil.getRequest().getSession(false);
195         if (session != null) {
196             final Map<String, String[]> resultUrlCache = getResultDocIdsCache(session);
197             final String[] urls = resultUrlCache.get(queryId);
198             if (urls != null) {
199                 return urls;
200             }
201         }
202         return StringUtil.EMPTY_STRINGS;
203     }
204 
205     private Map<String, String[]> getResultDocIdsCache(final HttpSession session) {
206         @SuppressWarnings("unchecked")
207         Map<String, String[]> resultDocIdsCache = (Map<String, String[]>) session.getAttribute(Constants.RESULT_DOC_ID_CACHE);
208         if (resultDocIdsCache == null) {
209             resultDocIdsCache = new LruHashMap<>(resultDocIdsCacheSize);
210             session.setAttribute(Constants.RESULT_DOC_ID_CACHE, resultDocIdsCache);
211         }
212         return resultDocIdsCache;
213     }
214 
215     public void setResultDocIdsCacheSize(final int resultDocIdsCacheSize) {
216         this.resultDocIdsCacheSize = resultDocIdsCacheSize;
217     }
218 
219     public void setCookieName(final String cookieName) {
220         this.cookieName = cookieName;
221     }
222 
223     public void setCookieDomain(final String cookieDomain) {
224         this.cookieDomain = cookieDomain;
225     }
226 
227     public void setCookieMaxAge(final int cookieMaxAge) {
228         this.cookieMaxAge = cookieMaxAge;
229     }
230 
231     public void setCookiePath(final String cookiePath) {
232         this.cookiePath = cookiePath;
233     }
234 
235     public void setCookieSecure(final Boolean cookieSecure) {
236         this.cookieSecure = cookieSecure;
237     }
238 
239     public void setCookieHttpOnly(final boolean httpOnly) {
240         this.httpOnly = httpOnly;
241     }
242 }