View Javadoc
1   /*
2    * Copyright 2012-2017 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.app.web.admin.accesstoken;
17  
18  import static org.codelibs.core.stream.StreamUtil.split;
19  import static org.codelibs.core.stream.StreamUtil.stream;
20  
21  import java.util.stream.Collectors;
22  
23  import javax.annotation.Resource;
24  
25  import org.codelibs.core.beans.util.BeanUtil;
26  import org.codelibs.core.lang.StringUtil;
27  import org.codelibs.fess.Constants;
28  import org.codelibs.fess.app.pager.AccessTokenPager;
29  import org.codelibs.fess.app.service.AccessTokenService;
30  import org.codelibs.fess.app.web.CrudMode;
31  import org.codelibs.fess.app.web.base.FessAdminAction;
32  import org.codelibs.fess.es.config.exentity.AccessToken;
33  import org.codelibs.fess.helper.PermissionHelper;
34  import org.codelibs.fess.helper.SystemHelper;
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  
44  /**
45   * @author shinsuke
46   */
47  public class AdminAccesstokenAction extends FessAdminAction {
48  
49      public static final String TOKEN = "token";
50  
51      public static final String EXPIRES = "expires";
52  
53      public static final String EXPIRED_TIME = "expiredTime";
54  
55      // ===================================================================================
56      //                                                                           Attribute
57      //                                                                           =========
58      @Resource
59      private AccessTokenService accessTokenService;
60      @Resource
61      private AccessTokenPager accessTokenPager;
62  
63      // ===================================================================================
64      //                                                                               Hook
65      //                                                                              ======
66      @Override
67      protected void setupHtmlData(final ActionRuntime runtime) {
68          super.setupHtmlData(runtime);
69          runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameAccesstoken()));
70      }
71  
72      // ===================================================================================
73      //                                                                      Search Execute
74      //                                                                      ==============
75      @Execute
76      public HtmlResponse index() {
77          return asListHtml();
78      }
79  
80      @Execute
81      public HtmlResponse list(final OptionalThing<Integer> pageNumber, final SearchForm form) {
82          pageNumber.ifPresent(num -> {
83              accessTokenPager.setCurrentPageNumber(pageNumber.get());
84          }).orElse(() -> {
85              accessTokenPager.setCurrentPageNumber(0);
86          });
87          return asHtml(path_AdminAccesstoken_AdminAccesstokenJsp).renderWith(data -> {
88              searchPaging(data, form);
89          });
90      }
91  
92      @Execute
93      public HtmlResponse search(final SearchForm form) {
94          copyBeanToBean(form, accessTokenPager, op -> op.exclude(Constants.PAGER_CONVERSION_RULE));
95          return asHtml(path_AdminAccesstoken_AdminAccesstokenJsp).renderWith(data -> {
96              searchPaging(data, form);
97          });
98      }
99  
100     @Execute
101     public HtmlResponse reset(final SearchForm form) {
102         accessTokenPager.clear();
103         return asHtml(path_AdminAccesstoken_AdminAccesstokenJsp).renderWith(data -> {
104             searchPaging(data, form);
105         });
106     }
107 
108     protected void searchPaging(final RenderData data, final SearchForm form) {
109         RenderDataUtil.register(data, "accessTokenItems", accessTokenService.getAccessTokenList(accessTokenPager)); // page navi
110 
111         // restore from pager
112         copyBeanToBean(accessTokenPager, form, op -> op.include("id"));
113     }
114 
115     // ===================================================================================
116     //                                                                        Edit Execute
117     //                                                                        ============
118     // -----------------------------------------------------
119     //                                            Entry Page
120     //                                            ----------
121     @Execute
122     public HtmlResponse createnew() {
123         saveToken();
124         return asEditHtml().useForm(CreateForm.class, op -> {
125             op.setup(form -> {
126                 form.initialize();
127                 form.crudMode = CrudMode.CREATE;
128             });
129         });
130     }
131 
132     // -----------------------------------------------------
133     //                                               Details
134     //                                               -------
135     @Execute
136     public HtmlResponse details(final int crudMode, final String id) {
137         verifyCrudMode(crudMode, CrudMode.DETAILS);
138         saveToken();
139         return asDetailsHtml().useForm(
140                 EditForm.class,
141                 op -> {
142                     op.setup(form -> {
143                         accessTokenService
144                                 .getAccessToken(id)
145                                 .ifPresent(
146                                         entity -> {
147                                             copyBeanToBean(entity, form, copyOp -> copyOp.exclude(Constants.PERMISSIONS, EXPIRED_TIME)
148                                                     .excludeNull().dateConverter(Constants.DEFAULT_DATETIME_FORMAT, EXPIRES));
149                                             final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
150                                             form.permissions =
151                                                     stream(entity.getPermissions()).get(
152                                                             stream -> stream.map(permissionHelper::decode).filter(StringUtil::isNotBlank)
153                                                                     .distinct().collect(Collectors.joining("\n")));
154                                             form.crudMode = crudMode;
155                                         })
156                                 .orElse(() -> {
157                                     throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id),
158                                             () -> asListHtml());
159                                 });
160                     });
161                 });
162     }
163 
164     @Execute
165     public HtmlResponse edit(final EditForm form) {
166         validate(form, messages -> {}, () -> asListHtml());
167         final String id = form.id;
168         accessTokenService
169                 .getAccessToken(id)
170                 .ifPresent(
171                         entity -> {
172                             copyBeanToBean(
173                                     entity,
174                                     form,
175                                     op -> op.exclude(Constants.PERMISSIONS, EXPIRED_TIME).dateConverter(Constants.DEFAULT_DATETIME_FORMAT,
176                                             EXPIRES));
177                             final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
178                             form.permissions =
179                                     stream(entity.getPermissions()).get(
180                                             stream -> stream.map(permissionHelper::decode).filter(StringUtil::isNotBlank).distinct()
181                                                     .collect(Collectors.joining("\n")));
182                         }).orElse(() -> {
183                     throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), () -> asListHtml());
184                 });
185         saveToken();
186         if (form.crudMode.intValue() == CrudMode.EDIT) {
187             // back
188             form.crudMode = CrudMode.DETAILS;
189             return asDetailsHtml();
190         } else {
191             form.crudMode = CrudMode.EDIT;
192             return asEditHtml();
193         }
194     }
195 
196     // -----------------------------------------------------
197     //                                         Actually Crud
198     //                                         -------------
199     @Execute
200     public HtmlResponse create(final CreateForm form) {
201         verifyCrudMode(form.crudMode, CrudMode.CREATE);
202         validate(form, messages -> {}, () -> asEditHtml());
203         verifyToken(() -> asEditHtml());
204         getAccessToken(form).ifPresent(
205                 entity -> {
206                     entity.setToken(systemHelper.generateAccessToken());
207                     try {
208                         accessTokenService.store(entity);
209                         saveInfo(messages -> messages.addSuccessCrudCreateCrudTable(GLOBAL));
210                     } catch (final Exception e) {
211                         throwValidationError(messages -> messages.addErrorsCrudFailedToCreateCrudTable(GLOBAL, buildThrowableMessage(e)),
212                                 () -> asEditHtml());
213                     }
214                 }).orElse(() -> {
215             throwValidationError(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL), () -> asEditHtml());
216         });
217         return redirect(getClass());
218     }
219 
220     @Execute
221     public HtmlResponse update(final EditForm form) {
222         verifyCrudMode(form.crudMode, CrudMode.EDIT);
223         validate(form, messages -> {}, () -> asEditHtml());
224         verifyToken(() -> asEditHtml());
225         getAccessToken(form).ifPresent(
226                 entity -> {
227                     try {
228                         accessTokenService.store(entity);
229                         saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
230                     } catch (final Exception e) {
231                         throwValidationError(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, buildThrowableMessage(e)),
232                                 () -> asEditHtml());
233                     }
234                 }).orElse(() -> {
235             throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.id), () -> asEditHtml());
236         });
237         return redirect(getClass());
238     }
239 
240     @Execute
241     public HtmlResponse delete(final EditForm form) {
242         verifyCrudMode(form.crudMode, CrudMode.DETAILS);
243         validate(form, messages -> {}, () -> asDetailsHtml());
244         verifyToken(() -> asDetailsHtml());
245         final String id = form.id;
246         accessTokenService
247                 .getAccessToken(id)
248                 .ifPresent(
249                         entity -> {
250                             try {
251                                 accessTokenService.delete(entity);
252                                 saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
253                             } catch (final Exception e) {
254                                 throwValidationError(
255                                         messages -> messages.addErrorsCrudFailedToDeleteCrudTable(GLOBAL, buildThrowableMessage(e)),
256                                         () -> asEditHtml());
257                             }
258                         }).orElse(() -> {
259                     throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), () -> asDetailsHtml());
260                 });
261         return redirect(getClass());
262     }
263 
264     // ===================================================================================
265     //                                                                        Assist Logic
266     //                                                                        ============
267 
268     private static OptionalEntity<AccessToken> getEntity(final CreateForm form, final String username, final long currentTime) {
269         switch (form.crudMode) {
270         case CrudMode.CREATE:
271             return OptionalEntity.of(new AccessToken()).map(entity -> {
272                 entity.setCreatedBy(username);
273                 entity.setCreatedTime(currentTime);
274                 return entity;
275             });
276         case CrudMode.EDIT:
277             if (form instanceof EditForm) {
278                 return ComponentUtil.getComponent(AccessTokenService.class).getAccessToken(((EditForm) form).id);
279             }
280             break;
281         default:
282             break;
283         }
284         return OptionalEntity.empty();
285     }
286 
287     public static OptionalEntity<AccessToken> getAccessToken(final CreateForm form) {
288         final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
289         final String username = systemHelper.getUsername();
290         final long currentTime = systemHelper.getCurrentTimeAsLong();
291         return getEntity(form, username, currentTime).map(
292                 entity -> {
293                     entity.setUpdatedBy(username);
294                     entity.setUpdatedTime(currentTime);
295                     BeanUtil.copyBeanToBean(form, entity,
296                             op -> op.exclude(Constants.COMMON_CONVERSION_RULE).exclude(TOKEN, Constants.PERMISSIONS, EXPIRED_TIME)
297                                     .dateConverter(Constants.DEFAULT_DATETIME_FORMAT, EXPIRES));
298                     final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
299                     entity.setPermissions(split(form.permissions, "\n").get(
300                             stream -> stream.map(s -> permissionHelper.encode(s)).filter(StringUtil::isNotBlank).distinct()
301                                     .toArray(n -> new String[n])));
302                     return entity;
303                 });
304     }
305 
306     // ===================================================================================
307     //                                                                        Small Helper
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     // ===================================================================================
318     //                                                                              JSP
319     //                                                                           =========
320 
321     private HtmlResponse asListHtml() {
322         return asHtml(path_AdminAccesstoken_AdminAccesstokenJsp).renderWith(data -> {
323             RenderDataUtil.register(data, "accessTokenItems", accessTokenService.getAccessTokenList(accessTokenPager));
324         }).useForm(SearchForm.class, setup -> {
325             setup.setup(form -> {
326                 copyBeanToBean(accessTokenPager, form, op -> op.include("id"));
327             });
328         });
329     }
330 
331     private HtmlResponse asEditHtml() {
332         return asHtml(path_AdminAccesstoken_AdminAccesstokenEditJsp);
333     }
334 
335     private HtmlResponse asDetailsHtml() {
336         return asHtml(path_AdminAccesstoken_AdminAccesstokenDetailsJsp);
337     }
338 
339 }