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.app.web.admin.general;
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.List;
23  import java.util.Map;
24  
25  import org.apache.logging.log4j.LogManager;
26  import org.apache.logging.log4j.Logger;
27  import org.codelibs.core.beans.util.BeanUtil;
28  import org.codelibs.core.lang.StringUtil;
29  import org.codelibs.core.misc.DynamicProperties;
30  import org.codelibs.fess.Constants;
31  import org.codelibs.fess.annotation.Secured;
32  import org.codelibs.fess.app.web.base.FessAdminAction;
33  import org.codelibs.fess.helper.SystemHelper;
34  import org.codelibs.fess.llm.LlmClient;
35  import org.codelibs.fess.llm.LlmClientManager;
36  import org.codelibs.fess.mylasta.direction.FessConfig;
37  import org.codelibs.fess.mylasta.mail.TestmailPostcard;
38  import org.codelibs.fess.util.ComponentUtil;
39  import org.lastaflute.core.mail.Postbox;
40  import org.lastaflute.web.Execute;
41  import org.lastaflute.web.response.HtmlResponse;
42  import org.lastaflute.web.ruts.process.ActionRuntime;
43  
44  import jakarta.annotation.Resource;
45  
46  /**
47   * Admin action for General settings.
48   *
49   */
50  public class AdminGeneralAction extends FessAdminAction {
51  
52      /**
53       * Default constructor.
54       */
55      public AdminGeneralAction() {
56          super();
57      }
58  
59      /** The role name for general settings administration. */
60      public static final String ROLE = "admin-general";
61  
62      private static final String DUMMY_PASSWORD = "**********";
63  
64      private static final Logger logger = LogManager.getLogger(AdminGeneralAction.class);
65  
66      // ===================================================================================
67      //                                                                           Attribute
68      //                                                                           =========
69      /** System properties for configuration management. */
70      @Resource
71      protected DynamicProperties systemProperties;
72  
73      // ===================================================================================
74      //                                                                               Hook
75      //                                                                              ======
76      @Override
77      protected void setupHtmlData(final ActionRuntime runtime) {
78          super.setupHtmlData(runtime);
79          runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameGeneral()));
80          runtime.registerData("dayItems", getDayItems());
81          final boolean ragEnabled = isRagSectionVisible();
82          runtime.registerData("ragEnabled", ragEnabled);
83          if (ragEnabled) {
84              runtime.registerData("ragLlmNameItems", getRagLlmNameItems());
85          }
86      }
87  
88      @Override
89      protected String getActionRole() {
90          return ROLE;
91      }
92  
93      // ===================================================================================
94      //
95  
96      /**
97       * Displays the general settings index page.
98       *
99       * @return HTML response for the general settings page
100      */
101     @Execute
102     @Secured({ ROLE, ROLE + VIEW })
103     public HtmlResponse index() {
104         saveToken();
105         return asHtml(path_AdminGeneral_AdminGeneralJsp).useForm(EditForm.class, setup -> {
106             setup.setup(form -> {
107                 updateForm(fessConfig, form);
108             });
109         });
110     }
111 
112     /**
113      * Sends a test mail using the provided notification settings.
114      *
115      * @param form the mail form containing notification settings
116      * @return HTML response after sending test mail
117      */
118     @Execute
119     @Secured({ ROLE })
120     public HtmlResponse sendmail(final MailForm form) {
121         validate(form, messages -> {}, () -> asHtml(path_AdminGeneral_AdminGeneralJsp));
122 
123         final String[] toAddresses = form.notificationTo.split(",");
124         final Map<String, Object> dataMap = new HashMap<>();
125         dataMap.put("hostname", systemHelper.getHostname());
126 
127         final FessConfig fessConfig = ComponentUtil.getFessConfig();
128         final Postbox postbox = ComponentUtil.getComponent(Postbox.class);
129         try {
130             TestmailPostcard.droppedInto(postbox, postcard -> {
131                 postcard.setFrom(fessConfig.getMailFromAddress(), fessConfig.getMailFromName());
132                 postcard.addReplyTo(fessConfig.getMailReturnPath());
133                 stream(toAddresses).of(stream -> stream.forEach(address -> {
134                     postcard.addTo(address);
135                 }));
136                 BeanUtil.copyMapToBean(dataMap, postcard);
137             });
138             saveInfo(messages -> messages.addSuccessSendTestmail(GLOBAL));
139             updateProperty(Constants.NOTIFICATION_TO_PROPERTY, form.notificationTo);
140             systemProperties.store();
141         } catch (final Exception e) {
142             logger.warn("Failed to send a test mail.", e);
143             saveError(messages -> messages.addErrorsFailedToSendTestmail(GLOBAL));
144         }
145 
146         return redirectByParam(AdminGeneralAction.class, "notificationTo", form.notificationTo);
147     }
148 
149     /**
150      * Updates the general system configuration settings.
151      *
152      * @param form the edit form containing updated settings
153      * @return HTML response after updating settings
154      */
155     @Execute
156     @Secured({ ROLE })
157     public HtmlResponse update(final EditForm form) {
158         validate(form, messages -> {}, () -> asHtml(path_AdminGeneral_AdminGeneralJsp));
159         verifyToken(() -> asHtml(path_AdminGeneral_AdminGeneralJsp));
160 
161         updateConfig(fessConfig, form);
162         saveInfo(messages -> messages.addSuccessUpdateCrawlerParams(GLOBAL));
163         return redirect(getClass());
164     }
165 
166     /**
167      * Updates the Fess configuration with values from the form.
168      *
169      * @param fessConfig the Fess configuration to update
170      * @param form the form containing new configuration values
171      */
172     public static void updateConfig(final FessConfig fessConfig, final EditForm form) {
173         fessConfig.setLoginRequired(isCheckboxEnabled(form.loginRequired));
174         fessConfig.setResultCollapsed(isCheckboxEnabled(form.resultCollapsed));
175         fessConfig.setLoginLinkEnabled(isCheckboxEnabled(form.loginLink));
176         fessConfig.setThumbnailEnabled(isCheckboxEnabled(form.thumbnail));
177         fessConfig.setIncrementalCrawling(isCheckboxEnabled(form.incrementalCrawling));
178         fessConfig.setDayForCleanup(form.dayForCleanup);
179         fessConfig.setCrawlingThreadCount(form.crawlingThreadCount);
180         fessConfig.setUserAgentName(form.crawlingUserAgent);
181         fessConfig.setSearchLog(isCheckboxEnabled(form.searchLog));
182         fessConfig.setUserInfo(isCheckboxEnabled(form.userInfo));
183         fessConfig.setUserFavorite(isCheckboxEnabled(form.userFavorite));
184         fessConfig.setWebApiJson(isCheckboxEnabled(form.webApiJson));
185         fessConfig.setSearchFileProxy(isCheckboxEnabled(form.searchFileProxy));
186         fessConfig.setUseBrowserLocaleForSearch(isCheckboxEnabled(form.searchUseBrowserLocale));
187         fessConfig.setSsoType(form.ssoType);
188         fessConfig.setAppValue(form.appValue);
189         fessConfig.setDefaultLabelValue(form.defaultLabelValue);
190         fessConfig.setDefaultSortValue(form.defaultSortValue);
191         fessConfig.setVirtualHostValue(form.virtualHostValue);
192         fessConfig.setAppendQueryParameter(isCheckboxEnabled(form.appendQueryParameter));
193         fessConfig.setIgnoreFailureType(form.ignoreFailureType != null ? form.ignoreFailureType : StringUtil.EMPTY);
194         fessConfig.setFailureCountThreshold(form.failureCountThreshold);
195         fessConfig.setWebApiPopularWord(isCheckboxEnabled(form.popularWord));
196         fessConfig.setCsvFileEncoding(form.csvFileEncoding);
197         fessConfig.setPurgeSearchLogDay(form.purgeSearchLogDay);
198         fessConfig.setPurgeJobLogDay(form.purgeJobLogDay);
199         fessConfig.setPurgeUserInfoDay(form.purgeUserInfoDay);
200         fessConfig.setPurgeByBots(form.purgeByBots != null ? form.purgeByBots : StringUtil.EMPTY);
201         fessConfig.setNotificationTo(form.notificationTo);
202         fessConfig.setSuggestSearchLog(isCheckboxEnabled(form.suggestSearchLog));
203         fessConfig.setSuggestDocuments(isCheckboxEnabled(form.suggestDocuments));
204         fessConfig.setPurgeSuggestSearchLogDay(form.purgeSuggestSearchLogDay);
205         fessConfig.setLdapProviderUrl(form.ldapProviderUrl);
206         fessConfig.setLdapSecurityPrincipal(form.ldapSecurityPrincipal);
207         fessConfig.setLdapAdminSecurityPrincipal(form.ldapAdminSecurityPrincipal);
208         if (form.ldapAdminSecurityCredentials != null && StringUtil.isNotBlank(form.ldapAdminSecurityCredentials.replace("*", " "))) {
209             fessConfig.setLdapAdminSecurityCredentials(form.ldapAdminSecurityCredentials);
210         }
211         fessConfig.setLdapBaseDn(form.ldapBaseDn);
212         fessConfig.setLdapAccountFilter(form.ldapAccountFilter);
213         fessConfig.setLdapGroupFilter(form.ldapGroupFilter);
214         fessConfig.setLdapMemberofAttribute(form.ldapMemberofAttribute != null ? form.ldapMemberofAttribute : StringUtil.EMPTY);
215         fessConfig.setLdapSecurityAuthentication(
216                 form.ldapSecurityAuthentication != null ? form.ldapSecurityAuthentication : StringUtil.EMPTY);
217         fessConfig.setLdapInitialContextFactory(form.ldapInitialContextFactory != null ? form.ldapInitialContextFactory : StringUtil.EMPTY);
218         fessConfig.setNotificationLogin(form.notificationLogin);
219         fessConfig.setNotificationSearchTop(form.notificationSearchTop);
220         fessConfig.setNotificationAdvanceSearch(form.notificationAdvanceSearch);
221         fessConfig.setSlackWebhookUrls(form.slackWebhookUrls);
222         fessConfig.setGoogleChatWebhookUrls(form.googleChatWebhookUrls);
223         fessConfig.setLogNotificationEnabled(isCheckboxEnabled(form.logNotificationEnabled));
224         if (StringUtil.isNotBlank(form.logNotificationLevel)) {
225             fessConfig.setLogNotificationLevel(form.logNotificationLevel);
226         }
227         fessConfig.setStorageEndpoint(form.storageEndpoint);
228         if (form.storageAccessKey != null && StringUtil.isNotBlank(form.storageAccessKey.replace("*", " "))) {
229             fessConfig.setStorageAccessKey(form.storageAccessKey);
230         }
231         if (form.storageSecretKey != null && StringUtil.isNotBlank(form.storageSecretKey.replace("*", " "))) {
232             fessConfig.setStorageSecretKey(form.storageSecretKey);
233         }
234         fessConfig.setStorageBucket(form.storageBucket);
235         fessConfig.setStorageType(form.storageType);
236         fessConfig.setStorageRegion(form.storageRegion);
237         fessConfig.setStorageProjectId(form.storageProjectId);
238         fessConfig.setStorageCredentialsPath(form.storageCredentialsPath);
239         if (form.ragLlmName != null && isValidRagLlmName(form.ragLlmName)) {
240             fessConfig.setRagLlmName(form.ragLlmName);
241         }
242 
243         // OpenID Connect
244         if (form.oicClientId != null && StringUtil.isNotBlank(form.oicClientId.replace("*", " "))) {
245             fessConfig.setSystemProperty("oic.client.id", form.oicClientId);
246         }
247         if (form.oicClientSecret != null && StringUtil.isNotBlank(form.oicClientSecret.replace("*", " "))) {
248             fessConfig.setSystemProperty("oic.client.secret", form.oicClientSecret);
249         }
250         fessConfig.setSystemProperty("oic.auth.server.url", form.oicAuthServerUrl);
251         fessConfig.setSystemProperty("oic.token.server.url", form.oicTokenServerUrl);
252         fessConfig.setSystemProperty("oic.redirect.url", form.oicRedirectUrl);
253         fessConfig.setSystemProperty("oic.scope", form.oicScope);
254         fessConfig.setSystemProperty("oic.base.url", form.oicBaseUrl);
255         fessConfig.setSystemProperty("oic.default.groups", form.oicDefaultGroups);
256         fessConfig.setSystemProperty("oic.default.roles", form.oicDefaultRoles);
257 
258         // SAML
259         fessConfig.setSystemProperty("saml.idp.entityid", form.samlIdpEntityid);
260         fessConfig.setSystemProperty("saml.idp.single_sign_on_service.url", form.samlIdpSingleSignOnServiceUrl);
261         fessConfig.setSystemProperty("saml.idp.single_logout_service.url", form.samlIdpSingleLogoutServiceUrl);
262         fessConfig.setSystemProperty("saml.idp.x509cert", form.samlIdpX509cert);
263         fessConfig.setSystemProperty("saml.sp.base.url", form.samlSpBaseUrl);
264         fessConfig.setSystemProperty("saml.sp.entityid", form.samlSpEntityid);
265         fessConfig.setSystemProperty("saml.sp.assertion_consumer_service.url", form.samlSpAssertionConsumerServiceUrl);
266         fessConfig.setSystemProperty("saml.sp.single_logout_service.url", form.samlSpSingleLogoutServiceUrl);
267         fessConfig.setSystemProperty("saml.sp.nameidformat", form.samlSpNameidformat);
268         fessConfig.setSystemProperty("saml.attribute.group.name", form.samlAttributeGroupName);
269         fessConfig.setSystemProperty("saml.attribute.role.name", form.samlAttributeRoleName);
270         fessConfig.setSystemProperty("saml.default.groups", form.samlDefaultGroups);
271         fessConfig.setSystemProperty("saml.default.roles", form.samlDefaultRoles);
272 
273         // SPNEGO
274         fessConfig.setSystemProperty("spnego.krb5.conf", form.spnegoKrb5Conf);
275         fessConfig.setSystemProperty("spnego.login.conf", form.spnegoLoginConf);
276         fessConfig.setSystemProperty("spnego.login.client.module", form.spnegoLoginClientModule);
277         fessConfig.setSystemProperty("spnego.login.server.module", form.spnegoLoginServerModule);
278         fessConfig.setSystemProperty("spnego.preauth.username", form.spnegoPreauthUsername);
279         if (form.spnegoPreauthPassword != null && StringUtil.isNotBlank(form.spnegoPreauthPassword.replace("*", " "))) {
280             fessConfig.setSystemProperty("spnego.preauth.password", form.spnegoPreauthPassword);
281         }
282         fessConfig.setSystemProperty("spnego.allow.basic", String.valueOf(isCheckboxEnabled(form.spnegoAllowBasic)));
283         fessConfig.setSystemProperty("spnego.allow.unsecure.basic", String.valueOf(isCheckboxEnabled(form.spnegoAllowUnsecureBasic)));
284         fessConfig.setSystemProperty("spnego.prompt.ntlm", String.valueOf(isCheckboxEnabled(form.spnegoPromptNtlm)));
285         fessConfig.setSystemProperty("spnego.allow.localhost", String.valueOf(isCheckboxEnabled(form.spnegoAllowLocalhost)));
286         fessConfig.setSystemProperty("spnego.allow.delegation", String.valueOf(isCheckboxEnabled(form.spnegoAllowDelegation)));
287         fessConfig.setSystemProperty("spnego.exclude.dirs", form.spnegoExcludeDirs);
288         fessConfig.setSystemProperty("spnego.logger.level", form.spnegoLoggerLevel);
289 
290         // Entra ID
291         if (form.entraidClientId != null && StringUtil.isNotBlank(form.entraidClientId.replace("*", " "))) {
292             fessConfig.setSystemProperty("entraid.client.id", form.entraidClientId);
293         }
294         if (form.entraidClientSecret != null && StringUtil.isNotBlank(form.entraidClientSecret.replace("*", " "))) {
295             fessConfig.setSystemProperty("entraid.client.secret", form.entraidClientSecret);
296         }
297         fessConfig.setSystemProperty("entraid.tenant", form.entraidTenant);
298         fessConfig.setSystemProperty("entraid.authority", form.entraidAuthority);
299         fessConfig.setSystemProperty("entraid.reply.url", form.entraidReplyUrl);
300         fessConfig.setSystemProperty("entraid.state.ttl", form.entraidStateTtl);
301         fessConfig.setSystemProperty("entraid.default.groups", form.entraidDefaultGroups);
302         fessConfig.setSystemProperty("entraid.default.roles", form.entraidDefaultRoles);
303         fessConfig.setSystemProperty("entraid.permission.fields", form.entraidPermissionFields);
304         fessConfig.setSystemProperty("entraid.use.ds", String.valueOf(isCheckboxEnabled(form.entraidUseDs)));
305 
306         fessConfig.storeSystemProperties();
307         ComponentUtil.getLdapManager().updateConfig();
308         final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
309         systemHelper.refreshDesignJspFiles();
310         systemHelper.updateSystemProperties();
311 
312         if (StringUtil.isNotBlank(form.logLevel)) {
313             systemHelper.setLogLevel(form.logLevel);
314         }
315         if (StringUtil.isNotBlank(form.llmLogLevel)) {
316             systemHelper.setLlmLogLevel(form.llmLogLevel);
317         }
318     }
319 
320     /**
321      * Updates the form with current configuration values.
322      *
323      * @param fessConfig the current Fess configuration
324      * @param form the form to populate with configuration values
325      */
326     public static void updateForm(final FessConfig fessConfig, final EditForm form) {
327         form.loginRequired = fessConfig.isLoginRequired() ? Constants.TRUE : Constants.FALSE;
328         form.resultCollapsed = fessConfig.isResultCollapsed() ? Constants.TRUE : Constants.FALSE;
329         form.loginLink = fessConfig.isLoginLinkEnabled() ? Constants.TRUE : Constants.FALSE;
330         form.thumbnail = fessConfig.isThumbnailEnabled() ? Constants.TRUE : Constants.FALSE;
331         form.incrementalCrawling = fessConfig.isIncrementalCrawling() ? Constants.TRUE : Constants.FALSE;
332         form.dayForCleanup = fessConfig.getDayForCleanup();
333         form.crawlingThreadCount = fessConfig.getCrawlingThreadCount();
334         form.crawlingUserAgent = fessConfig.getUserAgentName();
335         form.searchLog = fessConfig.isSearchLog() ? Constants.TRUE : Constants.FALSE;
336         form.userInfo = fessConfig.isUserInfo() ? Constants.TRUE : Constants.FALSE;
337         form.userFavorite = fessConfig.isUserFavorite() ? Constants.TRUE : Constants.FALSE;
338         form.webApiJson = fessConfig.isWebApiJson() ? Constants.TRUE : Constants.FALSE;
339         form.searchFileProxy = fessConfig.isSearchFileProxyEnabled() ? Constants.TRUE : Constants.FALSE;
340         form.searchUseBrowserLocale = fessConfig.isBrowserLocaleForSearchUsed() ? Constants.TRUE : Constants.FALSE;
341         form.ssoType = fessConfig.getSsoType();
342         form.appValue = fessConfig.getAppValue();
343         form.defaultLabelValue = fessConfig.getDefaultLabelValue();
344         form.defaultSortValue = fessConfig.getDefaultSortValue();
345         form.virtualHostValue = fessConfig.getVirtualHostValue();
346         form.appendQueryParameter = fessConfig.isAppendQueryParameter() ? Constants.TRUE : Constants.FALSE;
347         form.ignoreFailureType = fessConfig.getIgnoreFailureType();
348         form.failureCountThreshold = fessConfig.getFailureCountThreshold();
349         form.popularWord = fessConfig.isWebApiPopularWord() ? Constants.TRUE : Constants.FALSE;
350         form.csvFileEncoding = fessConfig.getCsvFileEncoding();
351         form.purgeSearchLogDay = fessConfig.getPurgeSearchLogDay();
352         form.purgeJobLogDay = fessConfig.getPurgeJobLogDay();
353         form.purgeUserInfoDay = fessConfig.getPurgeUserInfoDay();
354         form.purgeByBots = fessConfig.getPurgeByBots();
355         form.notificationTo = fessConfig.getNotificationTo();
356         form.suggestSearchLog = fessConfig.isSuggestSearchLog() ? Constants.TRUE : Constants.FALSE;
357         form.suggestDocuments = fessConfig.isSuggestDocuments() ? Constants.TRUE : Constants.FALSE;
358         form.purgeSuggestSearchLogDay = fessConfig.getPurgeSuggestSearchLogDay();
359         form.ldapProviderUrl = fessConfig.getLdapProviderUrl();
360         form.ldapSecurityPrincipal = fessConfig.getLdapSecurityPrincipal();
361         form.ldapAdminSecurityPrincipal = fessConfig.getLdapAdminSecurityPrincipal();
362         form.ldapAdminSecurityCredentials =
363                 StringUtil.isNotBlank(fessConfig.getLdapAdminSecurityCredentials()) ? DUMMY_PASSWORD : StringUtil.EMPTY;
364         form.ldapBaseDn = fessConfig.getLdapBaseDn();
365         form.ldapAccountFilter = fessConfig.getLdapAccountFilter();
366         form.ldapGroupFilter = fessConfig.getLdapGroupFilter();
367         form.ldapMemberofAttribute = fessConfig.getLdapMemberofAttribute();
368         form.ldapSecurityAuthentication = fessConfig.getLdapSecurityAuthentication();
369         form.ldapInitialContextFactory = fessConfig.getLdapInitialContextFactory();
370         form.notificationLogin = fessConfig.getNotificationLogin();
371         form.notificationSearchTop = fessConfig.getNotificationSearchTop();
372         form.notificationAdvanceSearch = fessConfig.getNotificationAdvanceSearch();
373         form.slackWebhookUrls = fessConfig.getSlackWebhookUrls();
374         form.googleChatWebhookUrls = fessConfig.getGoogleChatWebhookUrls();
375         form.logNotificationEnabled = fessConfig.isLogNotificationEnabled() ? Constants.TRUE : Constants.FALSE;
376         form.logNotificationLevel = fessConfig.getLogNotificationLevel();
377         form.storageEndpoint = fessConfig.getStorageEndpoint();
378         form.storageAccessKey = StringUtil.isNotBlank(fessConfig.getStorageAccessKey()) ? DUMMY_PASSWORD : StringUtil.EMPTY;
379         form.storageSecretKey = StringUtil.isNotBlank(fessConfig.getStorageSecretKey()) ? DUMMY_PASSWORD : StringUtil.EMPTY;
380         form.storageBucket = fessConfig.getStorageBucket();
381         form.storageType = fessConfig.getStorageType();
382         form.storageRegion = fessConfig.getStorageRegion();
383         form.storageProjectId = fessConfig.getStorageProjectId();
384         form.storageCredentialsPath = fessConfig.getStorageCredentialsPath();
385         form.ragLlmName = fessConfig.getRagLlmName();
386         form.llmLogLevel = ComponentUtil.getSystemHelper().getLlmLogLevel().toUpperCase();
387         form.logLevel = ComponentUtil.getSystemHelper().getLogLevel().toUpperCase();
388 
389         // OpenID Connect
390         form.oicClientId = StringUtil.isNotBlank(fessConfig.getSystemProperty("oic.client.id")) ? DUMMY_PASSWORD : StringUtil.EMPTY;
391         form.oicClientSecret = StringUtil.isNotBlank(fessConfig.getSystemProperty("oic.client.secret")) ? DUMMY_PASSWORD : StringUtil.EMPTY;
392         form.oicAuthServerUrl = fessConfig.getSystemProperty("oic.auth.server.url", "https://accounts.google.com/o/oauth2/auth");
393         form.oicTokenServerUrl = fessConfig.getSystemProperty("oic.token.server.url", "https://accounts.google.com/o/oauth2/token");
394         form.oicRedirectUrl = fessConfig.getSystemProperty("oic.redirect.url", StringUtil.EMPTY);
395         form.oicScope = fessConfig.getSystemProperty("oic.scope", StringUtil.EMPTY);
396         form.oicBaseUrl = fessConfig.getSystemProperty("oic.base.url", "http://localhost:8080");
397         form.oicDefaultGroups = fessConfig.getSystemProperty("oic.default.groups", StringUtil.EMPTY);
398         form.oicDefaultRoles = fessConfig.getSystemProperty("oic.default.roles", StringUtil.EMPTY);
399 
400         // SAML
401         form.samlIdpEntityid = fessConfig.getSystemProperty("saml.idp.entityid", StringUtil.EMPTY);
402         form.samlIdpSingleSignOnServiceUrl = fessConfig.getSystemProperty("saml.idp.single_sign_on_service.url", StringUtil.EMPTY);
403         form.samlIdpSingleLogoutServiceUrl = fessConfig.getSystemProperty("saml.idp.single_logout_service.url", StringUtil.EMPTY);
404         form.samlIdpX509cert = fessConfig.getSystemProperty("saml.idp.x509cert", StringUtil.EMPTY);
405         form.samlSpBaseUrl = fessConfig.getSystemProperty("saml.sp.base.url", "http://localhost:8080");
406         form.samlSpEntityid = fessConfig.getSystemProperty("saml.sp.entityid", StringUtil.EMPTY);
407         form.samlSpAssertionConsumerServiceUrl = fessConfig.getSystemProperty("saml.sp.assertion_consumer_service.url", StringUtil.EMPTY);
408         form.samlSpSingleLogoutServiceUrl = fessConfig.getSystemProperty("saml.sp.single_logout_service.url", StringUtil.EMPTY);
409         form.samlSpNameidformat = fessConfig.getSystemProperty("saml.sp.nameidformat", StringUtil.EMPTY);
410         form.samlAttributeGroupName = fessConfig.getSystemProperty("saml.attribute.group.name", "memberOf");
411         form.samlAttributeRoleName = fessConfig.getSystemProperty("saml.attribute.role.name", StringUtil.EMPTY);
412         form.samlDefaultGroups = fessConfig.getSystemProperty("saml.default.groups", StringUtil.EMPTY);
413         form.samlDefaultRoles = fessConfig.getSystemProperty("saml.default.roles", StringUtil.EMPTY);
414 
415         // SPNEGO
416         form.spnegoKrb5Conf = fessConfig.getSystemProperty("spnego.krb5.conf", "krb5.conf");
417         form.spnegoLoginConf = fessConfig.getSystemProperty("spnego.login.conf", "auth_login.conf");
418         form.spnegoLoginClientModule = fessConfig.getSystemProperty("spnego.login.client.module", "spnego-client");
419         form.spnegoLoginServerModule = fessConfig.getSystemProperty("spnego.login.server.module", "spnego-server");
420         form.spnegoPreauthUsername = fessConfig.getSystemProperty("spnego.preauth.username", StringUtil.EMPTY);
421         form.spnegoPreauthPassword =
422                 StringUtil.isNotBlank(fessConfig.getSystemProperty("spnego.preauth.password")) ? DUMMY_PASSWORD : StringUtil.EMPTY;
423         form.spnegoAllowBasic =
424                 Constants.TRUE.equalsIgnoreCase(fessConfig.getSystemProperty("spnego.allow.basic", Constants.TRUE)) ? Constants.TRUE
425                         : Constants.FALSE;
426         form.spnegoAllowUnsecureBasic =
427                 Constants.TRUE.equalsIgnoreCase(fessConfig.getSystemProperty("spnego.allow.unsecure.basic", Constants.TRUE))
428                         ? Constants.TRUE
429                         : Constants.FALSE;
430         form.spnegoPromptNtlm =
431                 Constants.TRUE.equalsIgnoreCase(fessConfig.getSystemProperty("spnego.prompt.ntlm", Constants.TRUE)) ? Constants.TRUE
432                         : Constants.FALSE;
433         form.spnegoAllowLocalhost =
434                 Constants.TRUE.equalsIgnoreCase(fessConfig.getSystemProperty("spnego.allow.localhost", Constants.TRUE)) ? Constants.TRUE
435                         : Constants.FALSE;
436         form.spnegoAllowDelegation =
437                 Constants.TRUE.equalsIgnoreCase(fessConfig.getSystemProperty("spnego.allow.delegation", Constants.FALSE)) ? Constants.TRUE
438                         : Constants.FALSE;
439         form.spnegoExcludeDirs = fessConfig.getSystemProperty("spnego.exclude.dirs", StringUtil.EMPTY);
440         form.spnegoLoggerLevel = fessConfig.getSystemProperty("spnego.logger.level", StringUtil.EMPTY);
441 
442         // Entra ID
443         form.entraidClientId = StringUtil.isNotBlank(fessConfig.getSystemProperty("entraid.client.id")) ? DUMMY_PASSWORD : StringUtil.EMPTY;
444         form.entraidClientSecret =
445                 StringUtil.isNotBlank(fessConfig.getSystemProperty("entraid.client.secret")) ? DUMMY_PASSWORD : StringUtil.EMPTY;
446         form.entraidTenant = fessConfig.getSystemProperty("entraid.tenant", StringUtil.EMPTY);
447         form.entraidAuthority = fessConfig.getSystemProperty("entraid.authority", "https://login.microsoftonline.com/");
448         form.entraidReplyUrl = fessConfig.getSystemProperty("entraid.reply.url", StringUtil.EMPTY);
449         form.entraidStateTtl = fessConfig.getSystemProperty("entraid.state.ttl", "3600");
450         form.entraidDefaultGroups = fessConfig.getSystemProperty("entraid.default.groups", StringUtil.EMPTY);
451         form.entraidDefaultRoles = fessConfig.getSystemProperty("entraid.default.roles", StringUtil.EMPTY);
452         form.entraidPermissionFields = fessConfig.getSystemProperty("entraid.permission.fields", "mail");
453         form.entraidUseDs = Constants.TRUE.equalsIgnoreCase(fessConfig.getSystemProperty("entraid.use.ds", Constants.TRUE)) ? Constants.TRUE
454                 : Constants.FALSE;
455     }
456 
457     private void updateProperty(final String key, final String value) {
458         systemProperties.setProperty(key, value == null ? StringUtil.EMPTY : value);
459     }
460 
461     private List<String> getDayItems() {
462         final List<String> items = new ArrayList<>();
463         for (int i = 0; i < 32; i++) {
464             items.add(Integer.toString(i));
465         }
466         for (int i = 40; i < 370; i += 10) {
467             items.add(Integer.toString(i));
468         }
469         items.add(Integer.toString(365));
470         return items;
471     }
472 
473     private boolean isRagSectionVisible() {
474         if (!fessConfig.isRagChatEnabled()) {
475             return false;
476         }
477         if (!ComponentUtil.hasComponent("llmClientManager")) {
478             return false;
479         }
480         final LlmClientManager llmClientManager = ComponentUtil.getComponent("llmClientManager");
481         return llmClientManager.getClients().length > 0;
482     }
483 
484     private List<Map<String, String>> getRagLlmNameItems() {
485         final List<Map<String, String>> itemList = new ArrayList<>();
486         final LlmClientManager llmClientManager = ComponentUtil.getComponent("llmClientManager");
487         for (final LlmClient client : llmClientManager.getClients()) {
488             final Map<String, String> map = new HashMap<>();
489             map.put(Constants.ITEM_LABEL, client.getName());
490             map.put(Constants.ITEM_VALUE, client.getName());
491             itemList.add(map);
492         }
493         return itemList;
494     }
495 
496     private static boolean isValidRagLlmName(final String name) {
497         if (!ComponentUtil.getFessConfig().isRagChatEnabled()) {
498             return false;
499         }
500         if (!ComponentUtil.hasComponent("llmClientManager")) {
501             return false;
502         }
503         final LlmClientManager llmClientManager = ComponentUtil.getComponent("llmClientManager");
504         for (final LlmClient client : llmClientManager.getClients()) {
505             if (name.equals(client.getName())) {
506                 return true;
507             }
508         }
509         return false;
510     }
511 
512 }