1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.helper;
17
18 import static org.codelibs.core.stream.StreamUtil.stream;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import javax.annotation.PostConstruct;
28 import javax.servlet.http.Cookie;
29 import javax.servlet.http.HttpServletRequest;
30
31 import org.codelibs.core.crypto.CachedCipher;
32 import org.codelibs.core.lang.StringUtil;
33 import org.codelibs.fess.app.service.AccessTokenService;
34 import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
35 import org.codelibs.fess.exception.InvalidAccessTokenException;
36 import org.codelibs.fess.mylasta.action.FessUserBean;
37 import org.codelibs.fess.mylasta.direction.FessConfig;
38 import org.codelibs.fess.util.ComponentUtil;
39 import org.lastaflute.web.servlet.request.RequestManager;
40 import org.lastaflute.web.util.LaRequestUtil;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49
50
51
52 public class RoleQueryHelper {
53
54 private static final String USER_ROLES = "userRoles";
55
56 private static final Logger logger = LoggerFactory.getLogger(RoleQueryHelper.class);
57
58 public CachedCipher cipher;
59
60 public String valueSeparator = "\n";
61
62 public String roleSeparator = ",";
63
64 public String parameterKey;
65
66 public boolean encryptedParameterValue = true;
67
68 public String headerKey;
69
70 public boolean encryptedHeaderValue = true;
71
72 public String cookieKey;
73
74 public boolean encryptedCookieValue = true;
75
76 protected Map<String, String> cookieNameMap;
77
78 private final List<String> defaultRoleList = new ArrayList<>();
79
80 @PostConstruct
81 public void init() {
82 stream(ComponentUtil.getFessConfig().getSearchDefaultPermissionsAsArray()).of(stream -> stream.forEach(name -> {
83 defaultRoleList.add(name);
84 }));
85 }
86
87 public Set<String> build(final SearchRequestType searchRequestType) {
88 final Set<String> roleSet = new HashSet<>();
89 final HttpServletRequest request = LaRequestUtil.getOptionalRequest().orElse(null);
90 final FessConfig fessConfig = ComponentUtil.getFessConfig();
91 final boolean isApiRequest =
92 !SearchRequestType.SEARCH.equals(searchRequestType) && !SearchRequestType.ADMIN_SEARCH.equals(searchRequestType);
93
94 if (request != null) {
95 @SuppressWarnings("unchecked")
96 final Set<String> list = (Set<String>) request.getAttribute(USER_ROLES);
97 if (list != null) {
98 return list;
99 }
100
101
102 if (StringUtil.isNotBlank(parameterKey)) {
103 processParameter(request, roleSet);
104 }
105
106
107 if (StringUtil.isNotBlank(headerKey)) {
108 processHeader(request, roleSet);
109 }
110
111
112 if (StringUtil.isNotBlank(cookieKey)) {
113 processCookie(request, roleSet);
114 }
115
116
117 if (cookieNameMap != null) {
118 buildByCookieNameMapping(request, roleSet);
119 }
120
121 if (isApiRequest) {
122 processAccessToken(request, roleSet);
123 }
124
125 final RequestManager requestManager = ComponentUtil.getRequestManager();
126 try {
127 requestManager.findUserBean(FessUserBean.class)
128 .ifPresent(fessUserBean -> stream(fessUserBean.getPermissions()).of(stream -> stream.forEach(roleSet::add)))
129 .orElse(() -> {
130 if (isApiRequest && ComponentUtil.getFessConfig().getApiAccessTokenRequiredAsBoolean()) {
131 throw new InvalidAccessTokenException("invalid_token", "Access token is requried.");
132 }
133 roleSet.addAll(fessConfig.getSearchGuestPermissionList());
134 });
135 } catch (final RuntimeException e) {
136 try {
137 requestManager.findLoginManager(FessUserBean.class).ifPresent(manager -> manager.logout());
138 } catch (final Exception e1) {
139
140 }
141 throw e;
142 }
143 }
144
145 if (defaultRoleList != null) {
146 roleSet.addAll(defaultRoleList);
147 }
148
149 if (logger.isDebugEnabled()) {
150 logger.debug("roleSet: " + roleSet);
151 }
152
153 if (request != null) {
154 request.setAttribute(USER_ROLES, roleSet);
155 }
156 return roleSet;
157 }
158
159 protected void processAccessToken(final HttpServletRequest request, final Set<String> roleSet) {
160 ComponentUtil.getComponent(AccessTokenService.class).getPermissions(request).ifPresent(p -> p.forEach(roleSet::add));
161 }
162
163 protected String getAccessToken(final HttpServletRequest request) {
164 final String token = request.getHeader("Authorization");
165 if (token != null) {
166 final String[] values = token.trim().split(" ");
167 if (values.length == 2 && "Bearer".equals(values[0])) {
168 return values[1];
169 }
170 throw new InvalidAccessTokenException("invalid_request", "Invalid format: " + token);
171 }
172 return request.getParameter("access_token");
173 }
174
175 protected void processParameter(final HttpServletRequest request, final Set<String> roleSet) {
176 final String parameter = request.getParameter(parameterKey);
177 if (logger.isDebugEnabled()) {
178 logger.debug(parameterKey + ":" + parameter);
179 }
180 if (StringUtil.isNotEmpty(parameter)) {
181 parseRoleSet(parameter, encryptedParameterValue, roleSet);
182 }
183
184 }
185
186 protected void processHeader(final HttpServletRequest request, final Set<String> roleSet) {
187
188 final String parameter = request.getHeader(headerKey);
189 if (logger.isDebugEnabled()) {
190 logger.debug(headerKey + ":" + parameter);
191 }
192 if (StringUtil.isNotEmpty(parameter)) {
193 parseRoleSet(parameter, encryptedHeaderValue, roleSet);
194 }
195
196 }
197
198 protected void processCookie(final HttpServletRequest request, final Set<String> roleSet) {
199
200 final Cookie[] cookies = request.getCookies();
201 if (cookies != null) {
202 for (final Cookie cookie : cookies) {
203 if (cookieKey.equals(cookie.getName())) {
204 final String value = cookie.getValue();
205 if (logger.isDebugEnabled()) {
206 logger.debug(cookieKey + ":" + value);
207 }
208 if (StringUtil.isNotEmpty(value)) {
209 parseRoleSet(value, encryptedCookieValue, roleSet);
210 }
211 }
212 }
213 }
214
215 }
216
217 protected void buildByCookieNameMapping(final HttpServletRequest request, final Set<String> roleSet) {
218 final Cookie[] cookies = request.getCookies();
219 if (cookies != null) {
220 for (final Cookie cookie : cookies) {
221 addRoleFromCookieMapping(roleSet, cookie);
222 }
223 }
224
225 }
226
227 protected void addRoleFromCookieMapping(final Set<String> roleNameList, final Cookie cookie) {
228 final String roleName = cookieNameMap.get(cookie.getName());
229 if (StringUtil.isNotBlank(roleName)) {
230 roleNameList.add(roleName);
231 }
232 }
233
234 protected void parseRoleSet(final String value, final boolean encrypted, final Set<String> roleSet) {
235 String rolesStr = value;
236 if (encrypted && cipher != null) {
237 rolesStr = cipher.decryptoText(rolesStr);
238 }
239
240 if (valueSeparator.length() > 0) {
241 final String[] values = rolesStr.split(valueSeparator);
242 if (values.length > 1) {
243 final String[] roles = values[1].split(roleSeparator);
244 for (final String role : roles) {
245 if (StringUtil.isNotEmpty(role)) {
246 roleSet.add(role);
247 }
248 }
249 }
250 } else {
251 final String[] roles = rolesStr.split(roleSeparator);
252 for (final String role : roles) {
253 if (StringUtil.isNotEmpty(role)) {
254 roleSet.add(role);
255 }
256 }
257 }
258 }
259
260 public void addCookieNameMapping(final String cookieName, final String roleName) {
261 if (cookieNameMap == null) {
262 cookieNameMap = new HashMap<>();
263 }
264 cookieNameMap.put(cookieName, roleName);
265 }
266
267 }