View Javadoc
1   /*
2    * Copyright 2012-2021 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.login;
17  
18  import javax.annotation.Resource;
19  import javax.servlet.http.HttpSession;
20  
21  import org.apache.logging.log4j.LogManager;
22  import org.apache.logging.log4j.Logger;
23  import org.codelibs.core.lang.StringUtil;
24  import org.codelibs.fess.app.service.UserService;
25  import org.codelibs.fess.app.web.base.FessLoginAction;
26  import org.codelibs.fess.app.web.base.login.LocalUserCredential;
27  import org.codelibs.fess.app.web.profile.ProfileAction;
28  import org.codelibs.fess.mylasta.action.FessUserBean;
29  import org.codelibs.fess.util.ComponentUtil;
30  import org.codelibs.fess.util.RenderDataUtil;
31  import org.dbflute.optional.OptionalEntity;
32  import org.dbflute.optional.OptionalThing;
33  import org.lastaflute.web.Execute;
34  import org.lastaflute.web.login.exception.LoginFailureException;
35  import org.lastaflute.web.response.HtmlResponse;
36  import org.lastaflute.web.validation.VaErrorHook;
37  
38  public class LoginAction extends FessLoginAction {
39  
40      private static final Logger logger = LogManager.getLogger(LoginAction.class);
41  
42      private static final String INVALID_OLD_PASSWORD = "LoginAction.invalidOldPassword";
43  
44      // ===================================================================================
45      // Attribute
46      //
47      @Resource
48      private UserService userService;
49  
50      // ===================================================================================
51      //                                                                       Login Execute
52      //                                                                      ==============
53  
54      @Execute
55      public HtmlResponse index() {
56          getSession().ifPresent(session -> session.removeAttribute(INVALID_OLD_PASSWORD));
57          return asIndexPage(null).useForm(LoginForm.class);
58      }
59  
60      private HtmlResponse asIndexPage(final LoginForm form) {
61          if (form != null) {
62              form.clearSecurityInfo();
63          }
64          return asHtml(virtualHost(path_Login_IndexJsp)).renderWith(data -> {
65              RenderDataUtil.register(data, "notification", fessConfig.getNotificationLogin());
66              saveToken();
67          });
68      }
69  
70      @Execute
71      public HtmlResponse login(final LoginForm form) {
72          validate(form, messages -> {}, () -> asIndexPage(form));
73          verifyToken(() -> asIndexPage(form));
74          final String username = form.username;
75          final String password = form.password;
76          form.clearSecurityInfo();
77          try {
78              final HtmlResponse loginRedirect = fessLoginAssist.loginRedirect(new LocalUserCredential(username, password), op -> {}, () -> {
79                  activityHelper.login(getUserBean());
80                  userInfoHelper.deleteUserCodeFromCookie(request);
81                  return getHtmlResponse();
82              });
83              if (ComponentUtil.getFessConfig().isValidAdminPassword(password)) {
84                  return loginRedirect;
85              }
86              getSession().ifPresent(session -> session.setAttribute(INVALID_OLD_PASSWORD, password));
87              return asHtml(virtualHost(path_Login_NewpasswordJsp));
88          } catch (final LoginFailureException lfe) {
89              activityHelper.loginFailure(OptionalThing.of(new LocalUserCredential(username, password)));
90              throwValidationError(messages -> messages.addErrorsLoginError(GLOBAL), () -> asIndexPage(form));
91          }
92          return redirect(getClass());
93      }
94  
95      @Execute
96      public HtmlResponse changePassword(final PasswordForm form) {
97          final VaErrorHook toIndexPage = () -> {
98              form.clearSecurityInfo();
99              return getUserBean().map(u -> asHtml(virtualHost(path_Login_NewpasswordJsp)).useForm(PasswordForm.class))
100                     .orElseGet(() -> redirect(LoginAction.class));
101         };
102         validatePasswordForm(form, toIndexPage);
103         final String username = getUserBean().map(FessUserBean::getUserId).get();
104         try {
105             userService.changePassword(username, form.password);
106             saveInfo(messages -> messages.addSuccessChangedPassword(GLOBAL));
107         } catch (final Exception e) {
108             logger.warn("Failed to change newPassword for {}", username, e);
109             throwValidationError(messages -> messages.addErrorsFailedToChangePassword(GLOBAL), toIndexPage);
110         }
111         getSession().ifPresent(session -> session.removeAttribute(INVALID_OLD_PASSWORD));
112         return redirect(ProfileAction.class);
113     }
114 
115     private void validatePasswordForm(final PasswordForm form, final VaErrorHook validationErrorLambda) {
116         validate(form, messages -> {}, validationErrorLambda);
117 
118         if (!form.password.equals(form.confirmPassword)) {
119             throwValidationError(messages -> {
120                 messages.addErrorsInvalidConfirmPassword(GLOBAL);
121             }, validationErrorLambda);
122         }
123 
124         final String oldPassword =
125                 getSession().map(session -> (String) session.getAttribute(INVALID_OLD_PASSWORD)).orElse(StringUtil.EMPTY);
126         fessLoginAssist.findLoginUser(new LocalUserCredential(getUserBean().get().getUserId(), oldPassword)).orElseGet(() -> {
127             throwValidationError(messages -> {
128                 messages.addErrorsNoUserForChangingPassword(GLOBAL);
129             }, validationErrorLambda);
130             return null;
131         });
132     }
133 
134     private OptionalThing<HttpSession> getSession() {
135         final HttpSession session = request.getSession(false);
136         if (session != null) {
137             return OptionalEntity.of(session);
138         }
139         return OptionalEntity.empty();
140     }
141 }