1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.app.web.admin.user;
17
18 import java.util.Base64;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import javax.annotation.Resource;
23
24 import org.apache.commons.lang3.ArrayUtils;
25 import org.codelibs.core.lang.StringUtil;
26 import org.codelibs.fess.Constants;
27 import org.codelibs.fess.app.pager.UserPager;
28 import org.codelibs.fess.app.service.GroupService;
29 import org.codelibs.fess.app.service.RoleService;
30 import org.codelibs.fess.app.service.UserService;
31 import org.codelibs.fess.app.web.CrudMode;
32 import org.codelibs.fess.app.web.base.FessAdminAction;
33 import org.codelibs.fess.app.web.base.login.FessLoginAssist;
34 import org.codelibs.fess.es.user.exentity.User;
35 import org.codelibs.fess.util.ComponentUtil;
36 import org.codelibs.fess.util.RenderDataUtil;
37 import org.dbflute.optional.OptionalEntity;
38 import org.dbflute.optional.OptionalThing;
39 import org.lastaflute.web.Execute;
40 import org.lastaflute.web.response.HtmlResponse;
41 import org.lastaflute.web.response.render.RenderData;
42 import org.lastaflute.web.ruts.process.ActionRuntime;
43 import org.lastaflute.web.validation.VaErrorHook;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48
49
50
51 public class AdminUserAction extends FessAdminAction {
52
53 private static final Logger logger = LoggerFactory.getLogger(AdminUserAction.class);
54
55
56
57
58 @Resource
59 private UserService userService;
60 @Resource
61 private RoleService roleService;
62 @Resource
63 private GroupService groupService;
64 @Resource
65 private UserPager userPager;
66
67
68
69
70 @Override
71 protected void setupHtmlData(final ActionRuntime runtime) {
72 super.setupHtmlData(runtime);
73 runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameUser()));
74 runtime.registerData("ldapAdminEnabled", fessConfig.isLdapAdminEnabled());
75 }
76
77
78
79
80 @Execute
81 public HtmlResponse index() {
82 return asListHtml();
83 }
84
85 @Execute
86 public HtmlResponse list(final OptionalThing<Integer> pageNumber, final SearchForm form) {
87 pageNumber.ifPresent(num -> {
88 userPager.setCurrentPageNumber(pageNumber.get());
89 }).orElse(() -> {
90 userPager.setCurrentPageNumber(0);
91 });
92 return asHtml(path_AdminUser_AdminUserJsp).renderWith(data -> {
93 searchPaging(data, form);
94 });
95 }
96
97 @Execute
98 public HtmlResponse search(final SearchForm form) {
99 copyBeanToBean(form, userPager, op -> op.exclude(Constants.PAGER_CONVERSION_RULE));
100 return asHtml(path_AdminUser_AdminUserJsp).renderWith(data -> {
101 searchPaging(data, form);
102 });
103 }
104
105 @Execute
106 public HtmlResponse reset(final SearchForm form) {
107 userPager.clear();
108 return asHtml(path_AdminUser_AdminUserJsp).renderWith(data -> {
109 searchPaging(data, form);
110 });
111 }
112
113 protected void searchPaging(final RenderData data, final SearchForm form) {
114 RenderDataUtil.register(data, "userItems", userService.getUserList(userPager));
115
116 copyBeanToBean(userPager, form, op -> op.include("id"));
117 }
118
119 private void registerForms(final RenderData data) {
120 RenderDataUtil.register(data, "roleItems", roleService.getAvailableRoleList());
121 RenderDataUtil.register(data, "groupItems", groupService.getAvailableGroupList());
122 }
123
124
125
126
127
128
129
130 @Execute
131 public HtmlResponse createnew() {
132 saveToken();
133 return asHtml(path_AdminUser_AdminUserEditJsp).useForm(CreateForm.class, op -> {
134 op.setup(form -> {
135 form.initialize();
136 form.crudMode = CrudMode.CREATE;
137 });
138 }).renderWith(data -> {
139 registerForms(data);
140 });
141 }
142
143 @Execute
144 public HtmlResponse edit(final EditForm form) {
145 validate(form, messages -> {}, () -> asListHtml());
146 final String id = form.id;
147 userService.getUser(id).ifPresent(entity -> {
148 copyBeanToBean(entity, form, op -> {});
149 }).orElse(() -> {
150 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), () -> asListHtml());
151 });
152 resetPassword(form);
153 saveToken();
154 if (form.crudMode.intValue() == CrudMode.EDIT) {
155
156 form.crudMode = CrudMode.DETAILS;
157 return asDetailsHtml();
158 } else {
159 form.crudMode = CrudMode.EDIT;
160 return asEditHtml();
161 }
162 }
163
164
165
166
167 @Execute
168 public HtmlResponse details(final int crudMode, final String id) {
169 verifyCrudMode(crudMode, CrudMode.DETAILS);
170 saveToken();
171 return asHtml(path_AdminUser_AdminUserDetailsJsp).useForm(EditForm.class, op -> {
172 op.setup(form -> {
173 userService.getUser(id).ifPresent(entity -> {
174 copyBeanToBean(entity, form, copyOp -> {
175 copyOp.excludeNull();
176 });
177 form.crudMode = crudMode;
178 }).orElse(() -> {
179 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), () -> asListHtml());
180 });
181 resetPassword(form);
182 });
183 }).renderWith(data -> {
184 registerForms(data);
185 });
186 }
187
188
189
190
191 @Execute
192 public HtmlResponse create(final CreateForm form) {
193 verifyCrudMode(form.crudMode, CrudMode.CREATE);
194 validate(form, messages -> {}, () -> asEditHtml());
195 verifyPassword(form, () -> asEditHtml());
196 verifyToken(() -> asEditHtml());
197 getUser(form).ifPresent(
198 entity -> {
199 try {
200 userService.store(entity);
201 saveInfo(messages -> messages.addSuccessCrudCreateCrudTable(GLOBAL));
202 } catch (final Exception e) {
203 logger.error("Failed to add " + entity, e);
204 throwValidationError(messages -> messages.addErrorsCrudFailedToCreateCrudTable(GLOBAL, buildThrowableMessage(e)),
205 () -> asEditHtml());
206 }
207 }).orElse(() -> {
208 throwValidationError(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL), () -> asEditHtml());
209 });
210 return redirect(getClass());
211 }
212
213 @Execute
214 public HtmlResponse update(final EditForm form) {
215 verifyCrudMode(form.crudMode, CrudMode.EDIT);
216 validate(form, messages -> {}, () -> asEditHtml());
217 verifyPassword(form, () -> asEditHtml());
218 verifyToken(() -> asEditHtml());
219 getUser(form).ifPresent(
220 entity -> {
221 try {
222 userService.store(entity);
223 saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
224 } catch (final Exception e) {
225 logger.error("Failed to update " + entity, e);
226 throwValidationError(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, buildThrowableMessage(e)),
227 () -> asEditHtml());
228 }
229 }).orElse(() -> {
230 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.id), () -> asEditHtml());
231 });
232 return redirect(getClass());
233 }
234
235 @Execute
236 public HtmlResponse delete(final EditForm form) {
237 verifyCrudMode(form.crudMode, CrudMode.DETAILS);
238 validate(form, messages -> {}, () -> asDetailsHtml());
239 getUserBean().ifPresent(u -> {
240 if (u.getFessUser() instanceof User && form.name.equals(u.getUserId())) {
241 throwValidationError(messages -> messages.addErrorsCouldNotDeleteLoggedInUser(GLOBAL), () -> asDetailsHtml());
242 }
243 });
244 verifyToken(() -> asDetailsHtml());
245 final String id = form.id;
246 userService
247 .getUser(id)
248 .ifPresent(
249 entity -> {
250 try {
251 userService.delete(entity);
252 saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
253 } catch (final Exception e) {
254 logger.error("Failed to delete " + entity, e);
255 throwValidationError(
256 messages -> messages.addErrorsCrudFailedToDeleteCrudTable(GLOBAL, buildThrowableMessage(e)),
257 () -> asDetailsHtml());
258 }
259 }).orElse(() -> {
260 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), () -> asDetailsHtml());
261 });
262 return redirect(getClass());
263 }
264
265
266
267
268 private static OptionalEntity<User> getEntity(final CreateForm form) {
269 switch (form.crudMode) {
270 case CrudMode.CREATE:
271 return OptionalEntity.of(new User()).map(entity -> {
272 entity.setId(Base64.getUrlEncoder().encodeToString(form.name.getBytes(Constants.CHARSET_UTF_8)));
273 return entity;
274 });
275 case CrudMode.EDIT:
276 if (form instanceof EditForm) {
277 return ComponentUtil.getComponent(UserService.class).getUser(((EditForm) form).id);
278 }
279 break;
280 default:
281 break;
282 }
283 return OptionalEntity.empty();
284 }
285
286 public static OptionalEntity<User> getUser(final CreateForm form) {
287 return getEntity(form).map(entity -> {
288 copyBeanToBean(form, entity, op -> op.exclude(ArrayUtils.addAll(Constants.COMMON_CONVERSION_RULE, "password")));
289 if (form.crudMode.intValue() == CrudMode.CREATE || StringUtil.isNotBlank(form.password)) {
290 final String encodedPassword = ComponentUtil.getComponent(FessLoginAssist.class).encryptPassword(form.password);
291 entity.setOriginalPassword(form.password);
292 entity.setPassword(encodedPassword);
293 }
294 return entity;
295 });
296 }
297
298 protected Map<String, String> createItem(final String label, final String value) {
299 final Map<String, String> map = new HashMap<>(2);
300 map.put(Constants.ITEM_LABEL, label);
301 map.put(Constants.ITEM_VALUE, value);
302 return map;
303 }
304
305
306
307
308
309 protected void verifyCrudMode(final int crudMode, final int expectedMode) {
310 if (crudMode != expectedMode) {
311 throwValidationError(messages -> {
312 messages.addErrorsCrudInvalidMode(GLOBAL, String.valueOf(expectedMode), String.valueOf(crudMode));
313 }, () -> asListHtml());
314 }
315 }
316
317 protected void verifyPassword(final CreateForm form, final VaErrorHook validationErrorLambda) {
318 if (form.crudMode == CrudMode.CREATE && StringUtil.isBlank(form.password)) {
319 resetPassword(form);
320 throwValidationError(messages -> {
321 messages.addErrorsBlankPassword("password");
322 }, validationErrorLambda);
323 }
324 if (form.password != null && !form.password.equals(form.confirmPassword)) {
325 form.confirmPassword = null;
326 throwValidationError(messages -> {
327 messages.addErrorsInvalidConfirmPassword("confirmPassword");
328 }, validationErrorLambda);
329 }
330 }
331
332 public static void resetPassword(final CreateForm form) {
333 form.password = null;
334 form.confirmPassword = null;
335 }
336
337
338
339
340
341 private HtmlResponse asListHtml() {
342 return asHtml(path_AdminUser_AdminUserJsp).renderWith(data -> {
343 RenderDataUtil.register(data, "userItems", userService.getUserList(userPager));
344 }).useForm(SearchForm.class, setup -> {
345 setup.setup(form -> {
346 copyBeanToBean(userPager, form, op -> op.include("id"));
347 });
348 });
349 }
350
351 private HtmlResponse asEditHtml() {
352 return asHtml(path_AdminUser_AdminUserEditJsp).renderWith(data -> {
353 registerForms(data);
354 });
355 }
356
357 private HtmlResponse asDetailsHtml() {
358 return asHtml(path_AdminUser_AdminUserDetailsJsp).renderWith(data -> {
359 registerForms(data);
360 });
361 }
362 }