View Javadoc
1   /*
2    * Copyright 2012-2025 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.mylasta.direction;
17  
18  import java.util.List;
19  import java.util.function.Consumer;
20  
21  import org.apache.logging.log4j.LogManager;
22  import org.apache.logging.log4j.Logger;
23  import org.codelibs.fess.app.web.base.FessAdminAction;
24  import org.codelibs.fess.mylasta.direction.sponsor.FessActionAdjustmentProvider;
25  import org.codelibs.fess.mylasta.direction.sponsor.FessApiFailureHook;
26  import org.codelibs.fess.mylasta.direction.sponsor.FessCookieResourceProvider;
27  import org.codelibs.fess.mylasta.direction.sponsor.FessCurtainBeforeHook;
28  import org.codelibs.fess.mylasta.direction.sponsor.FessCurtainFinallyHook;
29  import org.codelibs.fess.mylasta.direction.sponsor.FessJsonResourceProvider;
30  import org.codelibs.fess.mylasta.direction.sponsor.FessListedClassificationProvider;
31  import org.codelibs.fess.mylasta.direction.sponsor.FessMailDeliveryDepartmentCreator;
32  import org.codelibs.fess.mylasta.direction.sponsor.FessMultipartRequestHandler;
33  import org.codelibs.fess.mylasta.direction.sponsor.FessSecurityResourceProvider;
34  import org.codelibs.fess.mylasta.direction.sponsor.FessTimeResourceProvider;
35  import org.codelibs.fess.mylasta.direction.sponsor.FessUserLocaleProcessProvider;
36  import org.codelibs.fess.mylasta.direction.sponsor.FessUserTimeZoneProcessProvider;
37  import org.lastaflute.core.direction.CachedFwAssistantDirector;
38  import org.lastaflute.core.direction.FwAssistDirection;
39  import org.lastaflute.core.direction.FwCoreDirection;
40  import org.lastaflute.core.security.InvertibleCryptographer;
41  import org.lastaflute.core.security.OneWayCryptographer;
42  import org.lastaflute.db.dbflute.classification.ListedClassificationProvider;
43  import org.lastaflute.db.direction.FwDbDirection;
44  import org.lastaflute.web.direction.FwWebDirection;
45  import org.lastaflute.web.ruts.process.ActionRuntime;
46  import org.lastaflute.web.ruts.renderer.JspHtmlRenderingProvider;
47  
48  import jakarta.annotation.Resource;
49  
50  /**
51   * The framework assistant director for Fess.
52   *
53   * @author jflute
54   */
55  public class FessFwAssistantDirector extends CachedFwAssistantDirector {
56  
57      // ===================================================================================
58      //                                                                          Definition
59      //                                                                          ==========
60      private static final Logger logger = LogManager.getLogger(FessFwAssistantDirector.class);
61  
62      // ===================================================================================
63      //                                                                           Attribute
64      //                                                                           =========
65      @Resource
66      protected FessConfig fessConfig;
67  
68      // ===================================================================================
69      //                                                                              Assist
70      //                                                                              ======
71      @Override
72      protected void prepareAssistDirection(final FwAssistDirection direction) {
73          direction.directConfig(nameList -> nameList.add("fess_config.properties"), "fess_env.properties");
74      }
75  
76      // ===================================================================================
77      //                                                                               Core
78      //                                                                              ======
79      @Override
80      protected void prepareCoreDirection(final FwCoreDirection direction) {
81          // this configuration is on fess_env.properties because this is true only when development
82          direction.directDevelopmentHere(fessConfig.isDevelopmentHere());
83  
84          // titles of the application for logging are from configurations
85          direction.directLoggingTitle(fessConfig.getDomainTitle(), fessConfig.getEnvironmentTitle());
86  
87          // this configuration is on sea_env.properties because it has no influence to production
88          // even if you set true manually and forget to set false back
89          direction.directFrameworkDebug(fessConfig.isFrameworkDebug()); // basically false
90  
91          // you can add your own process when your application is booting or closing
92          direction.directCurtainBefore(createCurtainBeforeHook());
93          direction.directCurtainFinally(createCurtainFinallyHook()); // when destroy
94  
95          direction.directSecurity(createSecurityResourceProvider());
96          direction.directTime(createTimeResourceProvider());
97          direction.directMail(createFessMailDeliveryDepartmentCreator().create());
98          direction.directJson(createJsonResourceProvider());
99      }
100 
101     protected FessJsonResourceProvider createJsonResourceProvider() {
102         return new FessJsonResourceProvider();
103     }
104 
105     protected FessCurtainBeforeHook createCurtainBeforeHook() {
106         return new FessCurtainBeforeHook();
107     }
108 
109     protected FessCurtainFinallyHook createCurtainFinallyHook() {
110         return new FessCurtainFinallyHook();
111     }
112 
113     protected FessSecurityResourceProvider createSecurityResourceProvider() {
114         final InvertibleCryptographer inver;
115         final String cipherAlgorithm = fessConfig.getAppCipherAlgorithm();
116         if ("blowfish".equalsIgnoreCase(cipherAlgorithm)) {
117             logger.warn(
118                     "Blowfish cipher is deprecated due to its 64-bit block size vulnerability. Please consider migrating to AES. algorithm={}",
119                     cipherAlgorithm);
120             inver = InvertibleCryptographer.createBlowfishCipher(fessConfig.getAppCipherKey());
121         } else if ("des".equalsIgnoreCase(cipherAlgorithm)) {
122             logger.warn("DES cipher is deprecated due to its 56-bit key size vulnerability. Please consider migrating to AES. algorithm={}",
123                     cipherAlgorithm);
124             inver = InvertibleCryptographer.createDesCipher(fessConfig.getAppCipherKey());
125         } else if ("rsa".equalsIgnoreCase(cipherAlgorithm)) {
126             inver = InvertibleCryptographer.createRsaCipher(fessConfig.getAppCipherKey());
127         } else {
128             inver = InvertibleCryptographer.createAesCipher(fessConfig.getAppCipherKey());
129         }
130 
131         final OneWayCryptographer oneWay;
132         final String digestAlgorithm = fessConfig.getAppDigestAlgorithm();
133         if ("sha512".equalsIgnoreCase(digestAlgorithm)) {
134             oneWay = OneWayCryptographer.createSha512Cryptographer();
135         } else if ("md5".equalsIgnoreCase(digestAlgorithm)) {
136             logger.warn("MD5 digest is deprecated due to its collision vulnerabilities. Please consider migrating to SHA-256. algorithm={}",
137                     digestAlgorithm);
138             oneWay = new OneWayCryptographer("MD5", OneWayCryptographer.ENCODING_UTF8);
139         } else {
140             oneWay = OneWayCryptographer.createSha256Cryptographer();
141         }
142 
143         return new FessSecurityResourceProvider(inver, oneWay);
144     }
145 
146     protected FessTimeResourceProvider createTimeResourceProvider() {
147         return new FessTimeResourceProvider(fessConfig);
148     }
149 
150     protected FessMailDeliveryDepartmentCreator createFessMailDeliveryDepartmentCreator() {
151         return new FessMailDeliveryDepartmentCreator(fessConfig);
152     }
153 
154     // ===================================================================================
155     //                                                                                 DB
156     //                                                                                ====
157     @Override
158     protected void prepareDbDirection(final FwDbDirection direction) {
159         direction.directClassification(createListedClassificationProvider());
160     }
161 
162     protected ListedClassificationProvider createListedClassificationProvider() {
163         return new FessListedClassificationProvider();
164     }
165 
166     // ===================================================================================
167     //                                                                                Web
168     //                                                                               =====
169     @Override
170     protected void prepareWebDirection(final FwWebDirection direction) {
171         direction.directRequest(createUserLocaleProcessProvider(), createUserTimeZoneProcessProvider());
172         direction.directCookie(createCookieResourceProvider());
173         direction.directAdjustment(createActionAdjustmentProvider());
174         direction.directMessage(createMessageNameList(), "fess_label");
175         direction.directApiCall(createApiFailureHook());
176         direction.directMultipart(FessMultipartRequestHandler::new);
177         direction.directHtmlRendering(new JspHtmlRenderingProvider() {
178             @Override
179             protected String getShowErrorsForwardPath(final ActionRuntime runtime) {
180                 if (FessAdminAction.class.isAssignableFrom(runtime.getActionType())) {
181                     return "/admin/error/error.jsp";
182                 }
183                 return "/error/system.jsp";
184             }
185         });
186     }
187 
188     protected Consumer<List<String>> createMessageNameList() {
189         return nameList -> nameList.add("fess_message");
190     }
191 
192     protected FessUserLocaleProcessProvider createUserLocaleProcessProvider() {
193         return new FessUserLocaleProcessProvider();
194     }
195 
196     protected FessUserTimeZoneProcessProvider createUserTimeZoneProcessProvider() {
197         return new FessUserTimeZoneProcessProvider();
198     }
199 
200     protected FessCookieResourceProvider createCookieResourceProvider() { // #change_it_first
201         final InvertibleCryptographer cr = InvertibleCryptographer.createAesCipher("*unused@");
202         return new FessCookieResourceProvider(fessConfig, cr);
203     }
204 
205     protected FessActionAdjustmentProvider createActionAdjustmentProvider() {
206         return new FessActionAdjustmentProvider(fessConfig);
207     }
208 
209     protected FessApiFailureHook createApiFailureHook() {
210         return new FessApiFailureHook();
211     }
212 }