1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.helper;
17
18 import java.io.IOException;
19 import java.nio.file.attribute.AclFileAttributeView;
20 import java.nio.file.attribute.GroupPrincipal;
21 import java.nio.file.attribute.PosixFileAttributeView;
22 import java.nio.file.attribute.PosixFileAttributes;
23 import java.nio.file.attribute.UserPrincipal;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Locale;
27 import java.util.Map;
28
29 import org.apache.logging.log4j.LogManager;
30 import org.apache.logging.log4j.Logger;
31 import org.codelibs.core.lang.StringUtil;
32 import org.codelibs.fess.crawler.client.fs.FileSystemClient;
33 import org.codelibs.fess.crawler.client.ftp.FtpClient;
34 import org.codelibs.fess.crawler.client.smb.SmbClient;
35 import org.codelibs.fess.crawler.entity.ResponseData;
36 import org.codelibs.fess.crawler.exception.CrawlingAccessException;
37 import org.codelibs.fess.mylasta.direction.FessConfig;
38 import org.codelibs.fess.util.ComponentUtil;
39 import org.codelibs.jcifs.smb.SID;
40
41 import jakarta.annotation.Resource;
42
43
44
45
46
47
48 public class PermissionHelper {
49
50 private static final Logger logger = LogManager.getLogger(PermissionHelper.class);
51
52
53 protected String rolePrefix = "{role}";
54
55
56 protected String groupPrefix = "{group}";
57
58
59 protected String userPrefix = "{user}";
60
61
62 protected String allowPrefix = "(allow)";
63
64
65 protected String denyPrefix = "(deny)";
66
67
68 @Resource
69 protected SystemHelper systemHelper;
70
71
72
73
74
75 public PermissionHelper() {
76
77 }
78
79
80
81
82
83
84
85
86 public String encode(final String value) {
87 if (StringUtil.isBlank(value)) {
88 return null;
89 }
90
91 String permission = value.trim();
92 String lower = permission.toLowerCase(Locale.ROOT);
93 final String aclPrefix;
94 if (lower.startsWith(allowPrefix)) {
95 lower = lower.substring(allowPrefix.length());
96 permission = permission.substring(allowPrefix.length());
97 aclPrefix = StringUtil.EMPTY;
98 } else if (lower.startsWith(denyPrefix)) {
99 lower = lower.substring(denyPrefix.length());
100 permission = permission.substring(denyPrefix.length());
101 aclPrefix = ComponentUtil.getFessConfig().getRoleSearchDeniedPrefix();
102 } else {
103 aclPrefix = StringUtil.EMPTY;
104 }
105 if (StringUtil.isBlank(permission)) {
106 return null;
107 }
108 if (lower.startsWith(userPrefix)) {
109 if (permission.length() > userPrefix.length()) {
110 return aclPrefix + systemHelper.getSearchRoleByUser(permission.substring(userPrefix.length()));
111 }
112 return null;
113 }
114 if (lower.startsWith(groupPrefix)) {
115 if (permission.length() > groupPrefix.length()) {
116 return aclPrefix + systemHelper.getSearchRoleByGroup(permission.substring(groupPrefix.length()));
117 }
118 return null;
119 }
120 if (lower.startsWith(rolePrefix)) {
121 if (permission.length() > rolePrefix.length()) {
122 return aclPrefix + systemHelper.getSearchRoleByRole(permission.substring(rolePrefix.length()));
123 }
124 return null;
125 }
126 return permission;
127 }
128
129
130
131
132
133
134
135
136 public String decode(final String value) {
137 if (StringUtil.isBlank(value)) {
138 return null;
139 }
140
141 final FessConfig fessConfig = ComponentUtil.getFessConfig();
142 final String aclPrefix;
143 final String permission;
144 final String deniedPrefix = fessConfig.getRoleSearchDeniedPrefix();
145 if (value.startsWith(deniedPrefix)) {
146 permission = value.substring(deniedPrefix.length());
147 aclPrefix = denyPrefix;
148 } else {
149 permission = value;
150 aclPrefix = StringUtil.EMPTY;
151 }
152 if (StringUtil.isBlank(permission)) {
153 return null;
154 }
155 if (permission.startsWith(fessConfig.getRoleSearchUserPrefix())
156 && permission.length() > fessConfig.getRoleSearchUserPrefix().length()) {
157 return aclPrefix + userPrefix + permission.substring(fessConfig.getRoleSearchUserPrefix().length());
158 }
159 if (permission.startsWith(fessConfig.getRoleSearchGroupPrefix())
160 && permission.length() > fessConfig.getRoleSearchGroupPrefix().length()) {
161 return aclPrefix + groupPrefix + permission.substring(fessConfig.getRoleSearchGroupPrefix().length());
162 }
163 if (permission.startsWith(fessConfig.getRoleSearchRolePrefix())
164 && permission.length() > fessConfig.getRoleSearchRolePrefix().length()) {
165 return aclPrefix + rolePrefix + permission.substring(fessConfig.getRoleSearchRolePrefix().length());
166 }
167 return permission;
168 }
169
170
171
172
173
174
175 public void setRolePrefix(final String rolePrefix) {
176 this.rolePrefix = rolePrefix;
177 }
178
179
180
181
182
183
184 public void setGroupPrefix(final String groupPrefix) {
185 this.groupPrefix = groupPrefix;
186 }
187
188
189
190
191
192
193 public void setUserPrefix(final String userPrefix) {
194 this.userPrefix = userPrefix;
195 }
196
197
198
199
200
201
202
203
204 public List<String> getSmbRoleTypeList(final ResponseData responseData) {
205 final List<String> roleTypeList = new ArrayList<>();
206 final FessConfig fessConfig = ComponentUtil.getFessConfig();
207 if (fessConfig.isSmbRoleFromFile()) {
208 final SambaHelper sambaHelper = ComponentUtil.getSambaHelper();
209 final Map<String, Object> metaDataMap = responseData.getMetaDataMap();
210 if (responseData.getUrl().startsWith("smb:")) {
211 final SID[] allowedSids = (SID[]) metaDataMap.get(SmbClient.SMB_ALLOWED_SID_ENTRIES);
212 if (allowedSids != null) {
213 for (final SID sid : allowedSids) {
214 final String accountId = sambaHelper.getAccountId(sid);
215 if (accountId != null) {
216 roleTypeList.add(accountId);
217 }
218 }
219 }
220 final SID[] deniedSids = (SID[]) metaDataMap.get(SmbClient.SMB_DENIED_SID_ENTRIES);
221 if (deniedSids != null) {
222 for (final SID sid : deniedSids) {
223 final String accountId = sambaHelper.getAccountId(sid);
224 if (accountId != null) {
225 roleTypeList.add(fessConfig.getRoleSearchDeniedPrefix() + accountId);
226 }
227 }
228 }
229 if (logger.isDebugEnabled()) {
230 logger.debug("smbUrl:{} roleType:{}", responseData.getUrl(), roleTypeList);
231 }
232 } else if (responseData.getUrl().startsWith("smb1:")) {
233 final org.codelibs.jcifs.smb1.SID[] allowedSids = (org.codelibs.jcifs.smb1.SID[]) metaDataMap
234 .get(org.codelibs.fess.crawler.client.smb1.SmbClient.SMB_ALLOWED_SID_ENTRIES);
235 if (allowedSids != null) {
236 for (final org.codelibs.jcifs.smb1.SID sid : allowedSids) {
237 final String accountId = sambaHelper.getAccountId(sid);
238 if (accountId != null) {
239 roleTypeList.add(accountId);
240 }
241 }
242 }
243 final org.codelibs.jcifs.smb1.SID[] deniedSids = (org.codelibs.jcifs.smb1.SID[]) metaDataMap
244 .get(org.codelibs.fess.crawler.client.smb1.SmbClient.SMB_DENIED_SID_ENTRIES);
245 if (deniedSids != null) {
246 for (final org.codelibs.jcifs.smb1.SID sid : deniedSids) {
247 final String accountId = sambaHelper.getAccountId(sid);
248 if (accountId != null) {
249 roleTypeList.add(fessConfig.getRoleSearchDeniedPrefix() + accountId);
250 }
251 }
252 }
253 if (logger.isDebugEnabled()) {
254 logger.debug("smb1Url:{} roleType:{}", responseData.getUrl(), roleTypeList);
255 }
256 }
257 }
258 return roleTypeList;
259 }
260
261
262
263
264
265
266
267
268 public List<String> getFileRoleTypeList(final ResponseData responseData) {
269 final List<String> roleTypeList = new ArrayList<>();
270 final FessConfig fessConfig = ComponentUtil.getFessConfig();
271 if (fessConfig.isFileRoleFromFile() && responseData.getUrl().startsWith("file:")) {
272 final Map<String, Object> metaDataMap = responseData.getMetaDataMap();
273 final Object fileAttributeView = metaDataMap.get(FileSystemClient.FILE_ATTRIBUTE_VIEW);
274 try {
275 if (fileAttributeView instanceof final AclFileAttributeView aclFileAttributeView) {
276 aclFileAttributeView.getAcl().stream().forEach(acl -> {
277 final UserPrincipal principal = acl.principal();
278 if (logger.isDebugEnabled()) {
279 logger.debug("Principal: [{}] {}", principal.getClass().getName(), principal);
280 }
281 if (principal instanceof final GroupPrincipal groupPrincipal) {
282 roleTypeList.add(systemHelper.getSearchRoleByGroup(groupPrincipal.getName()));
283 } else if (principal != null) {
284 roleTypeList.add(systemHelper.getSearchRoleByUser(principal.getName()));
285 }
286 });
287 } else if (fileAttributeView instanceof final PosixFileAttributeView posixFileAttributeView) {
288 final PosixFileAttributes attributes = posixFileAttributeView.readAttributes();
289 final UserPrincipal userPrincipal = attributes.owner();
290 if (logger.isDebugEnabled()) {
291 logger.debug("Principal: [{}] {}", userPrincipal.getClass().getName(), userPrincipal);
292 }
293 if (userPrincipal != null) {
294 roleTypeList.add(systemHelper.getSearchRoleByUser(userPrincipal.getName()));
295 }
296 final GroupPrincipal groupPrincipal = attributes.group();
297 if (logger.isDebugEnabled()) {
298 logger.debug("Principal: [{}] {}", groupPrincipal.getClass().getName(), groupPrincipal);
299 }
300 if (groupPrincipal != null) {
301 roleTypeList.add(systemHelper.getSearchRoleByGroup(groupPrincipal.getName()));
302 }
303 }
304 } catch (final IOException e) {
305 throw new CrawlingAccessException("Failed to access permission info", e);
306 }
307 if (logger.isDebugEnabled()) {
308 logger.debug("fileUrl:{} roleType:{}", responseData.getUrl(), roleTypeList);
309 }
310 }
311 return roleTypeList;
312 }
313
314
315
316
317
318
319
320
321 public List<String> getFtpRoleTypeList(final ResponseData responseData) {
322 final List<String> roleTypeList = new ArrayList<>();
323 final FessConfig fessConfig = ComponentUtil.getFessConfig();
324 if (fessConfig.isFtpRoleFromFile() && responseData.getUrl().startsWith("ftp:")) {
325 final String owner = (String) responseData.getMetaDataMap().get(FtpClient.FTP_FILE_USER);
326 if (owner != null) {
327 roleTypeList.add(systemHelper.getSearchRoleByUser(owner));
328 }
329 final String group = (String) responseData.getMetaDataMap().get(FtpClient.FTP_FILE_GROUP);
330 if (group != null) {
331 roleTypeList.add(systemHelper.getSearchRoleByGroup(group));
332 }
333 if (logger.isDebugEnabled()) {
334 logger.debug("ftpUrl:{} roleType:{}", responseData.getUrl(), roleTypeList);
335 }
336 }
337 return roleTypeList;
338 }
339
340
341
342
343
344
345 public void setAllowPrefix(final String allowPrefix) {
346 this.allowPrefix = allowPrefix;
347 }
348
349
350
351
352
353
354 public void setDenyPrefix(final String denyPrefix) {
355 this.denyPrefix = denyPrefix;
356 }
357 }