فهرست منبع

fix #370 : add change password page

Shinsuke Sugaya 9 سال پیش
والد
کامیت
5d3360d147
25فایلهای تغییر یافته به همراه272 افزوده شده و 137 حذف شده
  1. 0 1
      src/main/java/org/codelibs/fess/app/service/GroupService.java
  2. 22 0
      src/main/java/org/codelibs/fess/app/service/UserService.java
  3. 36 28
      src/main/java/org/codelibs/fess/app/web/profile/ProfileAction.java
  4. 2 2
      src/main/java/org/codelibs/fess/app/web/profile/ProfileForm.java
  5. 26 0
      src/main/java/org/codelibs/fess/exception/FessUserNotFoundException.java
  6. 21 0
      src/main/java/org/codelibs/fess/ldap/LdapManager.java
  7. 2 0
      src/main/java/org/codelibs/fess/ldap/LdapUser.java
  8. 0 15
      src/main/java/org/codelibs/fess/mylasta/action/FessHtmlPath.java
  9. 20 2
      src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java
  10. 54 3
      src/main/java/org/codelibs/fess/mylasta/action/FessMessages.java
  11. 25 0
      src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java
  12. 1 0
      src/main/resources/fess_config.properties
  13. 8 2
      src/main/resources/fess_label.properties
  14. 8 2
      src/main/resources/fess_label_en.properties
  15. 10 3
      src/main/resources/fess_label_ja.properties
  16. 4 1
      src/main/resources/fess_message.properties
  17. 4 1
      src/main/resources/fess_message_en.properties
  18. 4 1
      src/main/resources/fess_message_ja.properties
  19. 0 8
      src/main/webapp/WEB-INF/view/login/footer.jsp
  20. 0 6
      src/main/webapp/WEB-INF/view/login/header.jsp
  21. 7 1
      src/main/webapp/WEB-INF/view/login/index.jsp
  22. 0 37
      src/main/webapp/WEB-INF/view/login/logout.jsp
  23. 0 8
      src/main/webapp/WEB-INF/view/profile/footer.jsp
  24. 0 6
      src/main/webapp/WEB-INF/view/profile/header.jsp
  25. 18 10
      src/main/webapp/WEB-INF/view/profile/index.jsp

+ 0 - 1
src/main/java/org/codelibs/fess/app/service/GroupService.java

@@ -23,7 +23,6 @@ import javax.annotation.Resource;
 import org.codelibs.core.beans.util.BeanUtil;
 import org.codelibs.fess.Constants;
 import org.codelibs.fess.app.pager.GroupPager;
-import org.codelibs.fess.es.user.bsbhv.BsGroupBhv;
 import org.codelibs.fess.es.user.cbean.GroupCB;
 import org.codelibs.fess.es.user.exbhv.GroupBhv;
 import org.codelibs.fess.es.user.exbhv.UserBhv;

+ 22 - 0
src/main/java/org/codelibs/fess/app/service/UserService.java

@@ -23,9 +23,12 @@ import javax.annotation.Resource;
 import org.codelibs.core.beans.util.BeanUtil;
 import org.codelibs.fess.Constants;
 import org.codelibs.fess.app.pager.UserPager;
+import org.codelibs.fess.app.web.base.login.FessLoginAssist;
 import org.codelibs.fess.es.user.cbean.UserCB;
 import org.codelibs.fess.es.user.exbhv.UserBhv;
 import org.codelibs.fess.es.user.exentity.User;
+import org.codelibs.fess.exception.FessUserNotFoundException;
+import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.util.ComponentUtil;
 import org.dbflute.cbean.result.PagingResultBean;
 import org.dbflute.optional.OptionalEntity;
@@ -37,6 +40,9 @@ public class UserService implements Serializable {
     @Resource
     protected UserBhv userBhv;
 
+    @Resource
+    protected FessLoginAssist fessLoginAssist;
+
     public List<User> getUserList(final UserPager userPager) {
 
         final PagingResultBean<User> userList = userBhv.selectPage(cb -> {
@@ -66,6 +72,22 @@ public class UserService implements Serializable {
 
     }
 
+    public void chnagePassword(String username, String password) {
+        ComponentUtil.getLdapManager().changePassword(username, password);
+
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        if (fessConfig.isLdapAdminEnabled() && fessConfig.isLdapAdminSyncPassword() || !fessConfig.isLdapAdminEnabled()) {
+            userBhv.selectEntity(cb -> cb.query().setName_Equal(username)).ifPresent(entity -> {
+                final String encodedPassword = fessLoginAssist.encryptPassword(password);
+                entity.setPassword(encodedPassword);
+                userBhv.insertOrUpdate(entity, op -> op.setRefresh(true));
+            }).orElse(() -> {
+                throw new FessUserNotFoundException(username);
+            });
+        }
+
+    }
+
     public void delete(final User user) {
         ComponentUtil.getLdapManager().delete(user);
 

+ 36 - 28
src/main/java/org/codelibs/fess/app/web/profile/ProfileAction.java

@@ -16,21 +16,25 @@
 
 /**
  * @author Keiichi Watanabe
+ * @author shinsuke
  */
 package org.codelibs.fess.app.web.profile;
 
 import javax.annotation.Resource;
 
-import org.codelibs.core.lang.StringUtil;
+import org.codelibs.fess.app.service.UserService;
 import org.codelibs.fess.app.web.base.FessSearchAction;
-import org.codelibs.fess.app.web.base.login.FessLoginAssist;
 import org.codelibs.fess.app.web.login.LoginAction;
 import org.lastaflute.web.Execute;
 import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.validation.VaErrorHook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ProfileAction extends FessSearchAction {
 
+    private static final Logger logger = LoggerFactory.getLogger(ProfileAction.class);
+
     // ===================================================================================
     // Constant
     //
@@ -39,7 +43,7 @@ public class ProfileAction extends FessSearchAction {
     // Attribute
     //
     @Resource
-    protected FessLoginAssist fessLoginAssist;
+    private UserService userService;
 
     // ===================================================================================
     // Hook
@@ -51,44 +55,48 @@ public class ProfileAction extends FessSearchAction {
 
     @Execute
     public HtmlResponse index() {
-        if (fessLoginAssist.getSessionUserBean().isPresent()) {
-            return asHtml(path_Profile_IndexJsp).useForm(ProfileForm.class);
-        } else {
-            return redirect(LoginAction.class);
-        }
+        return asIndexHtml();
     }
 
     @Execute
     public HtmlResponse changePassword(final ProfileForm form) {
-        validatePasswordForm(form, () -> index());
-        // TODO
+        VaErrorHook toIndexPage = () -> {
+            form.clearSecurityInfo();
+            return asIndexHtml();
+        };
+        validatePasswordForm(form, toIndexPage);
+        final String username = getUserBean().map(u -> u.getUserId()).get();
+        try {
+            userService.chnagePassword(username, form.newPassword);
+            saveInfo(messages -> messages.addSuccessChangedPassword(GLOBAL));
+        } catch (Exception e) {
+            logger.error("Failed to change password for " + username, e);
+            throwValidationError(messages -> messages.addErrorsFailedToChangePassword(GLOBAL), toIndexPage);
+        }
         return redirect(getClass());
     }
 
     private void validatePasswordForm(final ProfileForm form, final VaErrorHook validationErrorLambda) {
-        validate(form, messages -> {}, () -> {
-            form.clearSecurityInfo();
-            return index();
-        });
-        if (StringUtil.isBlank(form.oldPassword)) {
-            form.clearSecurityInfo();
-            throwValidationError(messages -> {
-                messages.addErrorsBlankPassword("oldPassword");
-            }, validationErrorLambda);
-        }
-        if (StringUtil.isBlank(form.newPassword)) {
+        validate(form, messages -> {}, validationErrorLambda);
+
+        if (!form.newPassword.equals(form.confirmNewPassword)) {
             form.newPassword = null;
-            form.confirmPassword = null;
+            form.confirmNewPassword = null;
             throwValidationError(messages -> {
-                messages.addErrorsBlankPassword("newPassword");
+                messages.addErrorsInvalidConfirmPassword(GLOBAL);
             }, validationErrorLambda);
         }
-        if (form.newPassword != null && !form.newPassword.equals(form.confirmPassword)) {
-            form.newPassword = null;
-            form.confirmPassword = null;
+
+        fessLoginAssist.findLoginUser(getUserBean().get().getUserId(), form.oldPassword).orElseGet(() -> {
             throwValidationError(messages -> {
-                messages.addErrorsInvalidConfirmPassword("confirmPassword");
+                messages.addErrorsNoUserForChangingPassword(GLOBAL);
             }, validationErrorLambda);
-        }
+            return null;
+        });
+    }
+
+    protected HtmlResponse asIndexHtml() {
+        return getUserBean().map(u -> asHtml(path_Profile_IndexJsp).useForm(ProfileForm.class))
+                .orElseGet(() -> redirect(LoginAction.class));
     }
 }

+ 2 - 2
src/main/java/org/codelibs/fess/app/web/profile/ProfileForm.java

@@ -33,12 +33,12 @@ public class ProfileForm implements Serializable {
     public String newPassword;
 
     @NotBlank
-    public String confirmPassword;
+    public String confirmNewPassword;
 
     public void clearSecurityInfo() {
         oldPassword = null;
         newPassword = null;
-        confirmPassword = null;
+        confirmNewPassword = null;
     }
 
 }

+ 26 - 0
src/main/java/org/codelibs/fess/exception/FessUserNotFoundException.java

@@ -0,0 +1,26 @@
+/*
+ * Copyright 2012-2016 CodeLibs Project and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.codelibs.fess.exception;
+
+public class FessUserNotFoundException extends FessSystemException {
+
+    private static final long serialVersionUID = 1L;
+
+    public FessUserNotFoundException(String username) {
+        super("User is not found: " + username);
+    }
+
+}

+ 21 - 0
src/main/java/org/codelibs/fess/ldap/LdapManager.java

@@ -424,6 +424,26 @@ public class LdapManager {
         });
     }
 
+    public void changePassword(String username, String password) {
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        if (!fessConfig.isLdapAdminEnabled()) {
+            return;
+        }
+
+        final Supplier<Hashtable<String, String>> adminEnv = () -> createAdminEnv();
+        final String userDN = fessConfig.getLdapAdminUserSecurityPrincipal(username);
+        search(fessConfig.getLdapAdminUserBaseDn(), fessConfig.getLdapAdminUserFilter(username), null, adminEnv, result -> {
+            if (result.hasMore()) {
+                final List<ModificationItem> modifyList = new ArrayList<>();
+                modifyReplaceEntry(modifyList, "userPassword", password);
+                modify(userDN, modifyList, adminEnv);
+            } else {
+                throw new LdapOperationException("User is not found: " + username);
+            }
+        });
+
+    }
+
     protected void insert(final String entryDN, final Attributes entry, final Supplier<Hashtable<String, String>> envSupplier) {
         try (DirContextHolder holder = getDirContext(envSupplier)) {
             logger.debug("Inserting {}", entryDN);
@@ -537,4 +557,5 @@ public class LdapManager {
             }
         }
     }
+
 }

+ 2 - 0
src/main/java/org/codelibs/fess/ldap/LdapUser.java

@@ -50,6 +50,8 @@ public class LdapUser implements FessUser {
             final String accountFilter = ComponentUtil.getFessConfig().getLdapAccountFilter();
             if (StringUtil.isNotBlank(baseDn) && StringUtil.isNotBlank(accountFilter)) {
                 roles = ComponentUtil.getLdapManager().getRoles(this, baseDn, accountFilter);
+            } else {
+                roles = StringUtil.EMPTY_STRINGS;
             }
         }
         return roles;

+ 0 - 15
src/main/java/org/codelibs/fess/mylasta/action/FessHtmlPath.java

@@ -317,24 +317,9 @@ public interface FessHtmlPath {
     /** The path of the HTML: /index.jsp */
     HtmlNext path_IndexJsp = new HtmlNext("/index.jsp");
 
-    /** The path of the HTML: /login/footer.jsp */
-    HtmlNext path_Login_FooterJsp = new HtmlNext("/login/footer.jsp");
-
-    /** The path of the HTML: /login/header.jsp */
-    HtmlNext path_Login_HeaderJsp = new HtmlNext("/login/header.jsp");
-
     /** The path of the HTML: /login/index.jsp */
     HtmlNext path_Login_IndexJsp = new HtmlNext("/login/index.jsp");
 
-    /** The path of the HTML: /login/logout.jsp */
-    HtmlNext path_Login_LogoutJsp = new HtmlNext("/login/logout.jsp");
-
-    /** The path of the HTML: /profile/footer.jsp */
-    HtmlNext path_Profile_FooterJsp = new HtmlNext("/profile/footer.jsp");
-
-    /** The path of the HTML: /profile/header.jsp */
-    HtmlNext path_Profile_HeaderJsp = new HtmlNext("/profile/header.jsp");
-
     /** The path of the HTML: /profile/index.jsp */
     HtmlNext path_Profile_IndexJsp = new HtmlNext("/profile/index.jsp");
 

+ 20 - 2
src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java

@@ -437,6 +437,15 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Login Required */
     public static final String LABELS_LOGIN_REQUIRED = "{labels.loginRequired}";
 
+    /** The key of the message: Current Password */
+    public static final String LABELS_OLD_PASSWORD = "{labels.oldPassword}";
+
+    /** The key of the message: New Password */
+    public static final String LABELS_NEW_PASSWORD = "{labels.newPassword}";
+
+    /** The key of the message: New Password(Confirm) */
+    public static final String LABELS_CONFIRM_NEW_PASSWORD = "{labels.confirmNewPassword}";
+
     /** The key of the message: System */
     public static final String LABELS_menu_system = "{labels.menu_system}";
 
@@ -770,7 +779,7 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Logout */
     public static final String LABELS_logout_button = "{labels.logout_button}";
 
-    /** The key of the message: Profile */
+    /** The key of the message: Change Password */
     public static final String LABELS_PROFILE = "{labels.profile}";
 
     /** The key of the message: Profile */
@@ -782,7 +791,10 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Update */
     public static final String LABELS_PROFILE_UPDATE = "{labels.profile.update}";
 
-    /** The key of the message: Old Password */
+    /** The key of the message: Back */
+    public static final String LABELS_PROFILE_BACK = "{labels.profile.back}";
+
+    /** The key of the message: Current Password */
     public static final String LABELS_PROFILE_placeholder_old_password = "{labels.profile.placeholder_old_password}";
 
     /** The key of the message: New Password */
@@ -1328,6 +1340,12 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Error Page (BadRequest) */
     public static final String LABELS_design_file_errorBadRequest = "{labels.design_file_errorBadRequest}";
 
+    /** The key of the message: Login Page */
+    public static final String LABELS_design_file_login = "{labels.design_file_login}";
+
+    /** The key of the message: Profile Page */
+    public static final String LABELS_design_file_profile = "{labels.design_file_profile}";
+
     /** The key of the message: Edit JSP File */
     public static final String LABELS_design_title_edit_content = "{labels.design_title_edit_content}";
 

+ 54 - 3
src/main/java/org/codelibs/fess/mylasta/action/FessMessages.java

@@ -273,7 +273,13 @@ public class FessMessages extends FessLabels {
     public static final String ERRORS_failed_to_send_testmail = "{errors.failed_to_send_testmail}";
 
     /** The key of the message: Could not find index for backup. */
-    public static final String ERRORS_COULD_NOT_FIND_BACKUP_INDEX = "{errors.could.not.find.backup.index}";
+    public static final String ERRORS_could_not_find_backup_index = "{errors.could_not_find_backup_index}";
+
+    /** The key of the message: The current password is incorrect. */
+    public static final String ERRORS_no_user_for_changing_password = "{errors.no_user_for_changing_password}";
+
+    /** The key of the message: Failed to change your password. */
+    public static final String ERRORS_failed_to_change_password = "{errors.failed_to_change_password}";
 
     /** The key of the message: The given query has unknown condition. */
     public static final String ERRORS_invalid_query_unknown = "{errors.invalid_query_unknown}";
@@ -350,6 +356,9 @@ public class FessMessages extends FessLabels {
     /** The key of the message: Deleted job logs. */
     public static final String SUCCESS_job_log_delete_all = "{success.job_log_delete_all}";
 
+    /** The key of the message: Changed your password. */
+    public static final String SUCCESS_changed_password = "{success.changed_password}";
+
     /** The key of the message: Created data. */
     public static final String SUCCESS_crud_create_crud_table = "{success.crud_create_crud_table}";
 
@@ -1576,7 +1585,7 @@ public class FessMessages extends FessLabels {
     }
 
     /**
-     * Add the created action message for the key 'errors.could.not.find.backup.index' with parameters.
+     * Add the created action message for the key 'errors.could_not_find_backup_index' with parameters.
      * <pre>
      * message: Could not find index for backup.
      * </pre>
@@ -1585,7 +1594,35 @@ public class FessMessages extends FessLabels {
      */
     public FessMessages addErrorsCouldNotFindBackupIndex(String property) {
         assertPropertyNotNull(property);
-        add(property, new ActionMessage(ERRORS_COULD_NOT_FIND_BACKUP_INDEX));
+        add(property, new ActionMessage(ERRORS_could_not_find_backup_index));
+        return this;
+    }
+
+    /**
+     * Add the created action message for the key 'errors.no_user_for_changing_password' with parameters.
+     * <pre>
+     * message: The current password is incorrect.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsNoUserForChangingPassword(String property) {
+        assertPropertyNotNull(property);
+        add(property, new ActionMessage(ERRORS_no_user_for_changing_password));
+        return this;
+    }
+
+    /**
+     * Add the created action message for the key 'errors.failed_to_change_password' with parameters.
+     * <pre>
+     * message: Failed to change your password.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsFailedToChangePassword(String property) {
+        assertPropertyNotNull(property);
+        add(property, new ActionMessage(ERRORS_failed_to_change_password));
         return this;
     }
 
@@ -1951,6 +1988,20 @@ public class FessMessages extends FessLabels {
         return this;
     }
 
+    /**
+     * Add the created action message for the key 'success.changed_password' with parameters.
+     * <pre>
+     * message: Changed your password.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addSuccessChangedPassword(String property) {
+        assertPropertyNotNull(property);
+        add(property, new ActionMessage(SUCCESS_changed_password));
+        return this;
+    }
+
     /**
      * Add the created action message for the key 'success.crud_create_crud_table' with parameters.
      * <pre>

+ 25 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -653,6 +653,9 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. groupOfNames */
     String LDAP_ADMIN_GROUP_OBJECT_CLASSES = "ldap.admin.group.object.classes";
 
+    /** The key of the configuration. e.g. true */
+    String LDAP_ADMIN_SYNC_PASSWORD = "ldap.admin.sync.password";
+
     /** The key of the configuration. e.g. memberOf */
     String LDAP_MEMBEROF_ATTRIBUTE = "ldap.memberof.attribute";
 
@@ -2600,6 +2603,20 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
      */
     String getLdapAdminGroupObjectClasses();
 
+    /**
+     * Get the value for the key 'ldap.admin.sync.password'. <br>
+     * The value is, e.g. true <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getLdapAdminSyncPassword();
+
+    /**
+     * Is the property for the key 'ldap.admin.sync.password' true? <br>
+     * The value is, e.g. true <br>
+     * @return The determination, true or false. (if not found, exception but basically no way)
+     */
+    boolean isLdapAdminSyncPassword();
+
     /**
      * Get the value for the key 'ldap.memberof.attribute'. <br>
      * The value is, e.g. memberOf <br>
@@ -3691,6 +3708,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             return get(FessConfig.LDAP_ADMIN_GROUP_OBJECT_CLASSES);
         }
 
+        public String getLdapAdminSyncPassword() {
+            return get(FessConfig.LDAP_ADMIN_SYNC_PASSWORD);
+        }
+
+        public boolean isLdapAdminSyncPassword() {
+            return is(FessConfig.LDAP_ADMIN_SYNC_PASSWORD);
+        }
+
         public String getLdapMemberofAttribute() {
             return get(FessConfig.LDAP_MEMBEROF_ATTRIBUTE);
         }

+ 1 - 0
src/main/resources/fess_config.properties

@@ -363,6 +363,7 @@ ldap.admin.role.object.classes=groupOfNames
 ldap.admin.group.filter=cn\=%s
 ldap.admin.group.base.dn=ou\=Group,dc\=fess,dc\=codelibs,dc\=org
 ldap.admin.group.object.classes=groupOfNames
+ldap.admin.sync.password=true
 
 ldap.memberof.attribute=memberOf
 #ldap.memberof.attribute=isMemberOf

+ 8 - 2
src/main/resources/fess_label.properties

@@ -138,6 +138,9 @@ labels.ldapSecurityPrincipal=Bind DN
 labels.ldapBaseDn=Base DN
 labels.ldapAccountFilter=Account Filter
 labels.loginRequired=Login Required
+labels.oldPassword=Current Password
+labels.newPassword=New Password
+labels.confirmNewPassword=New Password(Confirm)
 
 labels.menu_system=System
 labels.menu_wizard=Wizard
@@ -251,11 +254,12 @@ labels.logout_title=Logout
 labels.logout=Logout
 labels.do_you_want_to_logout=Do you want to logout?
 labels.logout_button=Logout
-labels.profile=Profile
+labels.profile=Change Password
 labels.profile_button=Profile
 labels.profile.title=Profile
 labels.profile.update=Update
-labels.profile.placeholder_old_password=Old Password
+labels.profile.back=Back
+labels.profile.placeholder_old_password=Current Password
 labels.profile.placeholder_new_password=New Password
 labels.profile.placeholder_confirm_new_password=Confirm New Password
 labels.top.search=Search
@@ -439,6 +443,8 @@ labels.design_file_errorNotFound=Error Page (Not Found)
 labels.design_file_errorSystem=Error Page (System Error)
 labels.design_file_errorRedirect=Error Page (Redirect)
 labels.design_file_errorBadRequest=Error Page (BadRequest)
+labels.design_file_login=Login Page
+labels.design_file_profile=Profile Page
 labels.design_title_edit_content=Edit JSP File
 labels.design_button_update=Update
 labels.design_button_back=Back

+ 8 - 2
src/main/resources/fess_label_en.properties

@@ -138,6 +138,9 @@ labels.ldapSecurityPrincipal=Bind DN
 labels.ldapBaseDn=Base DN
 labels.ldapAccountFilter=Account Filter
 labels.loginRequired=Login Required
+labels.oldPassword=Current Password
+labels.newPassword=New Password
+labels.confirmNewPassword=New Password(Confirm)
 
 labels.menu_system=System
 labels.menu_wizard=Wizard
@@ -251,11 +254,12 @@ labels.logout_title=Logout
 labels.logout=Logout
 labels.do_you_want_to_logout=Do you want to logout?
 labels.logout_button=Logout
-labels.profile=Profile
+labels.profile=Change Password
 labels.profile_button=Profile
 labels.profile.title=Profile
 labels.profile.update=Update
-labels.profile.placeholder_old_password=Old Password
+labels.profile.back=Back
+labels.profile.placeholder_old_password=Current Password
 labels.profile.placeholder_new_password=New Password
 labels.profile.placeholder_confirm_new_password=Confirm New Password
 labels.top.search=Search
@@ -439,6 +443,8 @@ labels.design_file_errorNotFound=Error Page (Not Found)
 labels.design_file_errorSystem=Error Page (System Error)
 labels.design_file_errorRedirect=Error Page (Redirect)
 labels.design_file_errorBadRequest=Error Page (BadRequest)
+labels.design_file_login=Login Page
+labels.design_file_profile=Profile Page
 labels.design_title_edit_content=Edit JSP File
 labels.design_button_update=Update
 labels.design_button_back=Back

+ 10 - 3
src/main/resources/fess_label_ja.properties

@@ -133,6 +133,10 @@ labels.term = \u691c\u7d22\u8a9e
 labels.searchParams = \u691c\u7d22\u30d1\u30e9\u30e1\u30fc\u30bf
 labels.fields = \u30d5\u30a3\u30fc\u30eb\u30c9
 labels.ex_q = \u62e1\u5f35\u30af\u30a8\u30ea\u30fc
+labels.oldPassword=\u73fe\u5728\u306e\u30d1\u30b9\u30ef\u30fc\u30c9
+labels.newPassword=\u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9
+labels.confirmNewPassword=\u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9(\u78ba\u8a8d)
+
 labels.menu_system = \u30b7\u30b9\u30c6\u30e0
 labels.menu_wizard = \u30a6\u30a3\u30b6\u30fc\u30c9
 labels.menu_crawl_config = \u5168\u822c
@@ -245,13 +249,14 @@ labels.logout_title = \u30ed\u30b0\u30a2\u30a6\u30c8
 labels.logout = \u30ed\u30b0\u30a2\u30a6\u30c8
 labels.do_you_want_to_logout = \u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3059\u304b\uff1f
 labels.logout_button = \u30ed\u30b0\u30a2\u30a6\u30c8
-labels.profile = \u8a2d\u5b9a
+labels.profile = \u30d1\u30b9\u30ef\u30fc\u30c9\u5909\u66f4
 labels.profile_button = \u8a2d\u5b9a
 labels.profile.title= \u8a2d\u5b9a
 labels.profile.update= \u66f4\u65b0
-labels.profile.placeholder_old_password= \u53e4\u3044\u30d1\u30b9\u30ef\u30fc\u30c9
+labels.profile.back= \u623b\u308b
+labels.profile.placeholder_old_password= \u73fe\u5728\u306e\u30d1\u30b9\u30ef\u30fc\u30c9
 labels.profile.placeholder_new_password= \u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9
-labels.profile.placeholder_confirm_new_password= \u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9\x28\u78ba\u8a8d\x29
+labels.profile.placeholder_confirm_new_password= \u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u78ba\u8a8d
 labels.top.search = \u691c\u7d22
 labels.index_title = Fess
 labels.index_form_search_btn = \u691c\u7d22
@@ -433,6 +438,8 @@ labels.design_file_errorNotFound = \u30a8\u30e9\u30fc\u30da\u30fc\u30b8 (\u898b\
 labels.design_file_errorSystem = \u30a8\u30e9\u30fc\u30da\u30fc\u30b8 (\u30b7\u30b9\u30c6\u30e0\u30a8\u30e9\u30fc) 
 labels.design_file_errorRedirect = \u30a8\u30e9\u30fc\u30da\u30fc\u30b8 (\u30ea\u30c0\u30a4\u30ec\u30af\u30c8) 
 labels.design_file_errorBadRequest = \u30a8\u30e9\u30fc\u30da\u30fc\u30b8 (BadRequest) 
+labels.design_file_login=\u30ed\u30b0\u30a4\u30f3\u30da\u30fc\u30b8
+labels.design_file_profile=\u8a2d\u5b9a\u30da\u30fc\u30b8
 labels.design_title_edit_content = \u30da\u30fc\u30b8\u306e\u7de8\u96c6\u30d5\u30a1\u30a4\u30eb\u306e\u8868\u793a
 labels.design_button_update = \u66f4\u65b0
 labels.design_button_back = \u623b\u308b

+ 4 - 1
src/main/resources/fess_message.properties

@@ -112,7 +112,9 @@ errors.invalid_confirm_password=Confirm Password does not match.
 errors.cannot_delete_doc_because_of_running=Crawler is running. The document cannot be deleted.
 errors.failed_to_delete_doc_in_admin=Failed to delete document.
 errors.failed_to_send_testmail=Failed to send the test mail.
-errors.could.not.find.backup.index=Could not find index for backup.
+errors.could_not_find_backup_index=Could not find index for backup.
+errors.no_user_for_changing_password=The current password is incorrect.
+errors.failed_to_change_password=Failed to change your password.
 
 errors.invalid_query_unknown=The given query has unknown condition.
 errors.invalid_query_parse_error=The given query is invalid.
@@ -141,6 +143,7 @@ success.upload_elevate_word=Uploaded Additional Word file.
 success.upload_bad_word=Uploaded Bad Word file.
 success.send_testmail=Sent the test mail.
 success.job_log_delete_all=Deleted job logs.
+success.changed_password=Changed your password.
 
 success.crud_create_crud_table=Created data.
 success.crud_update_crud_table=Updated data.

+ 4 - 1
src/main/resources/fess_message_en.properties

@@ -112,7 +112,9 @@ errors.invalid_confirm_password=Confirm Password does not match.
 errors.cannot_delete_doc_because_of_running=Crawler is running. The document cannot be deleted.
 errors.failed_to_delete_doc_in_admin=Failed to delete document.
 errors.failed_to_send_testmail=Failed to send the test mail.
-errors.could.not.find.backup.index=Could not find index for backup.
+errors.could_not_find_backup_index=Could not find index for backup.
+errors.no_user_for_changing_password=The current password is incorrect.
+errors.failed_to_change_password=Failed to change your password.
 
 errors.invalid_query_unknown=The given query has unknown condition.
 errors.invalid_query_parse_error=The given query is invalid.
@@ -141,6 +143,7 @@ success.upload_elevate_word=Uploaded Additional Word file.
 success.upload_bad_word=Uploaded Bad Word file.
 success.send_testmail=Sent the test mail.
 success.job_log_delete_all=Deleted job logs.
+success.changed_password=Changed your password.
 
 success.crud_create_crud_table=Created data.
 success.crud_update_crud_table=Updated data.

+ 4 - 1
src/main/resources/fess_message_ja.properties

@@ -116,7 +116,9 @@ errors.invalid_query_unsupported_sort_order = \u6307\u5b9a\u3055\u308c\u305f\u30
 errors.crud_invalid_mode = \u30e2\u30fc\u30c9\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002({0} \u3067\u306a\u304f\u3001{1} \u3067\u3059)
 errors.crud_failed_to_create_crud_table = \u65b0\u3057\u3044\u30c7\u30fc\u30bf\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
 errors.crud_could_not_find_crud_table = \u30c7\u30fc\u30bf {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
-errors.could.not.find.backup.index=\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u7528\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
+errors.could_not_find_backup_index=\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u7528\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
+errors.no_user_for_changing_password=\u73fe\u5728\u306e\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002
+errors.failed_to_change_password=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5909\u66f4\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
 
 success.update_crawler_params = \u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002
 success.delete_doc_from_index = \u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304b\u3089\u6587\u66f8\u3092\u524a\u9664\u3059\u308b\u30d7\u30ed\u30bb\u30b9\u3092\u958b\u59cb\u3057\u307e\u3057\u305f\u3002
@@ -135,6 +137,7 @@ success.upload_elevate_word = \u8ffd\u52a0\u30ef\u30fc\u30c9\u30d5\u30a1\u30a4\u
 success.upload_bad_word = \u9664\u5916\u30ef\u30fc\u30c9\u30d5\u30a1\u30a4\u30eb\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u307e\u3057\u305f\u3002
 success.send_testmail=\u30c6\u30b9\u30c8\u30e1\u30fc\u30eb\u3092\u9001\u4fe1\u3057\u307e\u3057\u305f\u3002
 success.job_log_delete_all=\u30b8\u30e7\u30d6\u30ed\u30b0\u3092\u524a\u9664\u3057\u307e\u3057\u305f\u3002
+success.changed_password=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5909\u66f4\u3057\u307e\u3057\u305f\u3002
 
 success.crud_create_crud_table = \u30c7\u30fc\u30bf\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u3002
 success.crud_update_crud_table = \u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002

+ 0 - 8
src/main/webapp/WEB-INF/view/login/footer.jsp

@@ -1,8 +0,0 @@
-<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
-<footer class="footer bd-footer text-muted" role="contentinfo">
-	<div class="container center">
-		<p class="text-muted">
-			<la:message key="labels.footer.copyright" />
-		</p>
-	</div>
-</footer>

+ 0 - 6
src/main/webapp/WEB-INF/view/login/header.jsp

@@ -1,6 +0,0 @@
-<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
-<nav class="navbar navbar-dark bg-inverse navbar-static-top pos-f-t">
-	<la:link styleClass="navbar-brand" href="/">
-		<img src="${f:url('/images/logo-head.png')}" alt="<la:message key="labels.header_brand_name" />" />
-	</la:link>
-</nav>

+ 7 - 1
src/main/webapp/WEB-INF/view/login/index.jsp

@@ -85,7 +85,13 @@
 	</div>
 	<!-- /.login-box -->
 
-	<jsp:include page="footer.jsp" />
+	<footer class="footer bd-footer text-muted" role="contentinfo">
+		<div class="container center">
+			<p class="text-muted">
+				<la:message key="labels.footer.copyright" />
+			</p>
+		</div>
+	</footer>
 
 	<input type="hidden" id="contextPath" value="${contextPath}" />
 	<script type="text/javascript"

+ 0 - 37
src/main/webapp/WEB-INF/view/login/logout.jsp

@@ -1,37 +0,0 @@
-<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<meta http-equiv="content-style-type" content="text/css" />
-<meta http-equiv="content-script-type" content="text/javascript" />
-<title><la:message key="labels.logout_title" /></title>
-<link href="${f:url('/css/admin/style-base.css')}" rel="stylesheet"
-	type="text/css" />
-<link href="${f:url('/css/admin/style.css')}" rel="stylesheet"
-	type="text/css" />
-</head>
-<body>
-	<jsp:include page="header.jsp" />
-	<div class="container">
-		<div class="content">
-			<div class="center row">
-				<div class="col-md-12">
-					<h2>
-						<la:message key="labels.logout" />
-					</h2>
-					<div class="message">
-						<la:message key="labels.do_you_want_to_logout" />
-					</div>
-					<div class="action">
-						<la:form>
-						<input type="submit" name="logout"
-							value="<la:message key="labels.logout_button"/>" />
-						</la:form>
-					</div>
-				</div>
-			</div>
-		</div>
-		<jsp:include page="footer.jsp" />
-	</div>
-</body>
-</html>

+ 0 - 8
src/main/webapp/WEB-INF/view/profile/footer.jsp

@@ -1,8 +0,0 @@
-<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
-<footer class="footer bd-footer text-muted" role="contentinfo">
-	<div class="container center">
-		<p class="text-muted">
-			<la:message key="labels.footer.copyright" />
-		</p>
-	</div>
-</footer>

+ 0 - 6
src/main/webapp/WEB-INF/view/profile/header.jsp

@@ -1,6 +0,0 @@
-<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
-<nav class="navbar navbar-dark bg-inverse navbar-static-top pos-f-t">
-	<la:link styleClass="navbar-brand" href="/">
-		<img src="${f:url('/images/logo-head.png')}" alt="<la:message key="labels.header_brand_name" />" />
-	</la:link>
-</nav>

+ 18 - 10
src/main/webapp/WEB-INF/view/profile/index.jsp

@@ -35,9 +35,6 @@
 			<p class="login-box-msg">
 				<la:message key="labels.profile" />
 			</p>
-			<p>
-				Username: ${username}
-			</p>
 			<%-- Message --%>
 			<div>
 				<la:info id="msg" message="false">
@@ -72,23 +69,28 @@
 						<c:set var="ph_confirm_password">
 							<la:message key="labels.profile.placeholder_confirm_new_password" />
 						</c:set>
-						<la:password property="confirmPassword" class="form-control"
+						<la:password property="confirmNewPassword" class="form-control"
 							     placeholder="${ph_confirm_password}" />
 					</div>
 				</div>
 				<div class="row">
-					<div class="col-xs-3"></div>
+					<div class="col-xs-2"></div>
 					<!-- /.col -->
-					<div class="col-xs-6">
+					<div class="col-xs-8">
+						<la:link href="/"
+							styleClass="btn btn-default">
+							<i class="fa fa-arrow-circle-left"></i>
+							<la:message key="labels.profile.back" />
+						</la:link>
 						<button type="submit" name="changePassword"
-							class="btn btn-primary btn-block btn-flat"
+							class="btn btn-warning"
 							value="<la:message key="labels.profile.update"/>">
-							<i class="fa fa-sign-in"></i>
+							<i class="fa fa-pencil"></i>
 							<la:message key="labels.profile.update" />
 						</button>
 					</div>
 					<!-- /.col -->
-					<div class="col-xs-3"></div>
+					<div class="col-xs-2"></div>
 					<!-- /.col -->
 				</div>
 			</la:form>
@@ -97,7 +99,13 @@
 	</div>
 	<!-- /.login-box -->
 
-	<jsp:include page="footer.jsp" />
+	<footer class="footer bd-footer text-muted" role="contentinfo">
+		<div class="container center">
+			<p class="text-muted">
+				<la:message key="labels.footer.copyright" />
+			</p>
+		</div>
+	</footer>
 
 	<input type="hidden" id="contextPath" value="${contextPath}" />
 	<script type="text/javascript"