浏览代码

add login feature

Shinsuke Sugaya 9 年之前
父节点
当前提交
f8bfac9359

+ 3 - 1
dbflute_fess/freegen/elasticsearch/AbstractEntity.vm

@@ -176,7 +176,9 @@ public abstract class AbstractEntity implements Entity, Serializable, Cloneable
 
 
     public abstract Map<String, Object> toSource();
     public abstract Map<String, Object> toSource();
 
 
-    public class DocMeta {
+    public class DocMeta implements Serializable {
+
+        private static final long serialVersionUID = 1L;
 
 
         protected String id;
         protected String id;
 
 

+ 0 - 3
pom.xml

@@ -114,9 +114,6 @@
 						<exclude>org/codelibs/fess/app/web/admin/DataAction.java</exclude>
 						<exclude>org/codelibs/fess/app/web/admin/DataAction.java</exclude>
 						<exclude>org/codelibs/fess/app/web/admin/WizardForm.java</exclude>
 						<exclude>org/codelibs/fess/app/web/admin/WizardForm.java</exclude>
 						<exclude>org/codelibs/fess/app/web/admin/FailureUrlForm.java</exclude>
 						<exclude>org/codelibs/fess/app/web/admin/FailureUrlForm.java</exclude>
-						<exclude>org/codelibs/fess/app/web/base/AbstractLoginAction.java</exclude>
-						<exclude>org/codelibs/fess/app/web/LoginAction.java</exclude>
-						<exclude>org/codelibs/fess/app/web/LoginForm.java</exclude>
 					</excludes>
 					</excludes>
 				</configuration>
 				</configuration>
 			</plugin>
 			</plugin>

+ 0 - 195
src/main/java/org/codelibs/fess/app/web/LoginAction.java

@@ -1,195 +0,0 @@
-/*
- * Copyright 2009-2015 the 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.app.web;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.codelibs.core.crypto.CachedCipher;
-import org.codelibs.core.lang.StringUtil;
-import org.codelibs.fess.Constants;
-import org.codelibs.fess.FessSystemException;
-import org.codelibs.fess.SSCConstants;
-import org.codelibs.fess.entity.LoginInfo;
-import org.codelibs.fess.helper.SystemHelper;
-import org.codelibs.fess.util.ActivityUtil;
-import org.codelibs.fess.util.ComponentUtil;
-import org.lastaflute.web.util.LaRequestUtil;
-import org.lastaflute.web.util.LaResponseUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class LoginAction implements Serializable {
-    private static final Logger logger = LoggerFactory.getLogger(LoginAction.class);
-
-    private static final long serialVersionUID = 1L;
-
-    //@ActionForm
-    @Resource
-    protected LoginForm loginForm;
-
-    @Resource
-    protected SystemHelper systemHelper;
-
-    //@Execute(validator = false, input = "../index")
-    public String index() {
-        final HttpServletRequest request = LaRequestUtil.getRequest();
-        final HttpSession session = request.getSession();
-        // check login session
-        final Object obj = session.getAttribute(SSCConstants.USER_INFO);
-        if (obj instanceof LoginInfo) {
-            final LoginInfo loginInfo = (LoginInfo) obj;
-            if (loginInfo.isAdministrator()) {
-                redirect(getAdminRootPath());
-                return null;
-            } else {
-                return "logout.jsp";
-            }
-        }
-
-        if ("logout".equals(loginForm.type)) {
-            if (logger.isInfoEnabled()) {
-                logger.info("Invalidated session. The username is " + request.getRemoteUser());
-            }
-            session.invalidate();
-        }
-
-        String returnPath;
-        if (StringUtil.isNotBlank(loginForm.returnPath)) {
-            final CachedCipher cipher = ComponentUtil.getCipher(Constants.AUTH_CIPHER);
-            if (cipher == null) {
-                throw new FessSystemException("A cipher for authentication is null. Please check a filter setting.");
-            }
-            final String value = cipher.decryptoText(loginForm.returnPath);
-            final int idx = value.indexOf('|');
-            if (idx >= 0) {
-                returnPath = value.substring(idx + 1);
-                LaRequestUtil.getRequest().getSession().setAttribute(Constants.RETURN_PATH, returnPath);
-            } else {
-                // invalid returnPath
-                LaRequestUtil.getRequest().getSession().removeAttribute(Constants.RETURN_PATH);
-            }
-        } else {
-            LaRequestUtil.getRequest().getSession().removeAttribute(Constants.RETURN_PATH);
-        }
-
-        return "login?redirect=true";
-    }
-
-    //@Execute(validator = false, input = "../index")
-    public String login() {
-        final HttpServletRequest request = LaRequestUtil.getRequest();
-        final HttpSession oldSession = request.getSession();
-
-        final Map<String, Object> sessionObjMap = new HashMap<String, Object>();
-        final Enumeration<String> e = oldSession.getAttributeNames();
-        while (e.hasMoreElements()) {
-            final String name = e.nextElement();
-            sessionObjMap.put(name, oldSession.getAttribute(name));
-        }
-        oldSession.invalidate();
-
-        sessionObjMap.remove(Globals.MESSAGE_KEY);
-
-        final HttpSession session = request.getSession();
-        for (final Map.Entry<String, Object> entry : sessionObjMap.entrySet()) {
-            session.setAttribute(entry.getKey(), entry.getValue());
-        }
-
-        // create user info
-        final LoginInfo loginInfo = new LoginInfo();
-        loginInfo.setUsername(request.getRemoteUser());
-        session.setAttribute(SSCConstants.USER_INFO, loginInfo);
-
-        String returnPath;
-        final Set<String> authenticatedRoleList = systemHelper.getAuthenticatedRoleSet();
-        final Set<String> roleSet = new HashSet<>();
-        for (final String role : authenticatedRoleList) {
-            if (request.isUserInRole(role)) {
-                roleSet.add(role);
-            }
-        }
-        loginInfo.setRoleSet(roleSet);
-
-        if (loginInfo.isAdministrator()) {
-            ActivityUtil.login(request.getRemoteUser(), request);
-
-            returnPath = (String) session.getAttribute(Constants.RETURN_PATH);
-            if (returnPath != null) {
-                session.removeAttribute(Constants.RETURN_PATH);
-            } else {
-                // admin page
-                returnPath = getAdminRootPath();
-            }
-        } else {
-            if (!loginInfo.getRoleSet().isEmpty()) {
-                ActivityUtil.login(request.getRemoteUser(), request);
-            } else {
-                if (logger.isWarnEnabled()) {
-                    logger.warn("Login Failure: " + request.getRemoteUser() + " does not have authenticated roles.");
-                }
-                // logout
-                session.invalidate();
-            }
-            returnPath = LaRequestUtil.getRequest().getContextPath();
-        }
-
-        redirect(returnPath);
-
-        return null;
-    }
-
-    private void redirect(final String returnPath) {
-        final HttpServletResponse response = LaResponseUtil.getResponse();
-        try {
-            response.sendRedirect(response.encodeURL(returnPath));
-        } catch (final IOException e) {
-            throw new FessSystemException("Failed to redirect to " + returnPath, e);
-        }
-    }
-
-    private String getAdminRootPath() {
-        String returnPath = LaRequestUtil.getRequest().getContextPath();
-        if (StringUtil.isEmpty(returnPath) || "/".equals(returnPath)) {
-            returnPath = "/admin";
-        } else {
-            returnPath = returnPath + "/admin";
-        }
-        return returnPath;
-    }
-
-    //@Execute(validator = false, input = "../index")
-    public String logout() {
-        final HttpServletRequest request = LaRequestUtil.getRequest();
-        ActivityUtil.logout(request.getRemoteUser(), request);
-
-        final HttpSession session = request.getSession();
-        session.invalidate();
-
-        return "login?redirect=true";
-    }
-}

+ 0 - 29
src/main/java/org/codelibs/fess/app/web/LoginForm.java

@@ -1,29 +0,0 @@
-/*
- * Copyright 2009-2015 the 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.app.web;
-
-import java.io.Serializable;
-
-public class LoginForm implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    public String returnPath;
-
-    public String type;
-
-}

+ 0 - 179
src/main/java/org/codelibs/fess/app/web/base/AbstractLoginAction.java

@@ -1,179 +0,0 @@
-/*
- * Copyright 2012 the 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.app.web.base;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.codelibs.core.crypto.CachedCipher;
-import org.codelibs.core.lang.StringUtil;
-import org.codelibs.fess.SSCConstants;
-import org.codelibs.fess.entity.UserInfo;
-import org.codelibs.fess.exception.LoginException;
-import org.codelibs.fess.struts.form.AbstractLoginForm;
-import org.codelibs.fess.util.ActivityUtil;
-import org.lastaflute.web.LastaWebKey;
-import org.lastaflute.web.util.LaResponseUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractLoginAction implements Serializable {
-    private static final Logger logger = LoggerFactory.getLogger(AbstractLoginAction.class);
-
-    private static final long serialVersionUID = 1L;
-
-    @Resource
-    protected HttpServletRequest request;
-
-    @Resource
-    protected CachedCipher authCipher;
-
-    protected String doIndex(final AbstractLoginForm form) {
-        HttpSession session = request.getSession(false);
-        // check login session
-        final Object obj = session == null ? null : session.getAttribute(SSCConstants.USER_INFO);
-        if (obj instanceof UserInfo) {
-            redirect(getAuthRootPath());
-            return null;
-        }
-
-        String params = null;
-        if ("forbidden".equals(form.type)) {
-            // invalid user
-            if (logger.isInfoEnabled()) {
-                logger.info("ISSC0001", new Object[] { request.getRemoteUser() });
-            }
-            if (session != null) {
-                session = invalidateSession(session);
-            }
-            params = "msgs=error.login_error";
-        }
-
-        if (session == null) {
-            session = request.getSession();
-        }
-
-        String path;
-        if (StringUtil.isNotBlank(form.returnPath)) {
-            final String value = authCipher.decryptoText(form.returnPath);
-            final int idx = value.indexOf('|');
-            if (idx >= 0) {
-                path = value.substring(idx + 1);
-                session.setAttribute(SSCConstants.RETURN_PATH, path);
-            } else {
-                // invalid returnPathName
-                session.removeAttribute(SSCConstants.RETURN_PATH);
-            }
-        } else {
-            session.removeAttribute(SSCConstants.RETURN_PATH);
-        }
-
-        return getLoginPath(params);
-    }
-
-    protected String doLogin(final AbstractLoginForm form) {
-        final HttpSession oldSession = request.getSession();
-
-        final HttpSession session = invalidateSession(oldSession);
-
-        session.removeAttribute(LastaWebKey.ACTION_INFO_KEY);
-
-        // create user info
-        final UserInfo loginInfo = new UserInfo();
-        loginInfo.setUsername(request.getRemoteUser());
-        session.setAttribute(SSCConstants.USER_INFO, loginInfo);
-
-        String returnPath = (String) session.getAttribute(SSCConstants.RETURN_PATH);
-        if (returnPath != null) {
-            session.removeAttribute(SSCConstants.RETURN_PATH);
-        } else {
-            // admin page
-            returnPath = getAuthRootPath();
-        }
-
-        ActivityUtil.login(loginInfo.getUsername(), request);
-
-        redirect(returnPath);
-
-        return null;
-    }
-
-    private HttpSession invalidateSession(final HttpSession oldSession) {
-        final Map<String, Object> sessionObjMap = new HashMap<String, Object>();
-        @SuppressWarnings("unchecked")
-        final Enumeration<String> e = oldSession.getAttributeNames();
-        while (e.hasMoreElements()) {
-            final String name = e.nextElement();
-            sessionObjMap.put(name, oldSession.getAttribute(name));
-        }
-        oldSession.invalidate();
-
-        final HttpSession session = request.getSession();
-        for (final Map.Entry<String, Object> entry : sessionObjMap.entrySet()) {
-            session.setAttribute(entry.getKey(), entry.getValue());
-        }
-        return session;
-    }
-
-    protected String doLogout(final AbstractLoginForm form) {
-        ActivityUtil.login(request.getRemoteUser(), request);
-
-        final HttpSession session = request.getSession();
-        session.invalidate();
-
-        return getLoginPath(null);
-    }
-
-    protected String getDefaultPath() {
-        return "/index?redirect=true";
-    }
-
-    protected String getLoginPath(final String params) {
-        final StringBuilder buf = new StringBuilder();
-        buf.append("login?");
-        if (params != null && params.length() > 0) {
-            buf.append(params).append('&');
-        }
-        buf.append("redirect=true");
-        return buf.toString();
-    }
-
-    protected String getAuthRootPath() {
-        final String contextPath = request.getContextPath();
-        if (StringUtil.isEmpty(contextPath) || "/".equals(contextPath)) {
-            return "/admin/";
-        } else {
-            return contextPath + "/admin/";
-        }
-    }
-
-    protected void redirect(final String returnPath) {
-        final HttpServletResponse response = LaResponseUtil.getResponse();
-        try {
-            response.sendRedirect(response.encodeURL(returnPath));
-        } catch (final IOException e) {
-            throw new LoginException("ESSC0002", new Object[] { returnPath }, e);
-        }
-    }
-}

+ 10 - 0
src/main/java/org/codelibs/fess/app/web/base/FessAdminAction.java

@@ -22,7 +22,9 @@ import javax.servlet.ServletContext;
 import org.codelibs.core.beans.util.BeanUtil;
 import org.codelibs.core.beans.util.BeanUtil;
 import org.codelibs.core.beans.util.CopyOptions;
 import org.codelibs.core.beans.util.CopyOptions;
 import org.codelibs.fess.mylasta.action.FessMessages;
 import org.codelibs.fess.mylasta.action.FessMessages;
+import org.dbflute.optional.OptionalThing;
 import org.lastaflute.di.util.LdiFileUtil;
 import org.lastaflute.di.util.LdiFileUtil;
+import org.lastaflute.web.login.LoginManager;
 import org.lastaflute.web.util.LaServletContextUtil;
 import org.lastaflute.web.util.LaServletContextUtil;
 import org.lastaflute.web.validation.VaMessenger;
 import org.lastaflute.web.validation.VaMessenger;
 
 
@@ -75,4 +77,12 @@ public abstract class FessAdminAction extends FessBaseAction {
     public void document1_CallableSuperMethod() {
     public void document1_CallableSuperMethod() {
         super.document1_CallableSuperMethod();
         super.document1_CallableSuperMethod();
     }
     }
+
+    // ===================================================================================
+    //                                                                           User Info
+    //                                                                           =========
+    @Override
+    protected OptionalThing<LoginManager> myLoginManager() {
+        return OptionalThing.of(fessLoginAssist);
+    }
 }
 }

+ 1 - 11
src/main/java/org/codelibs/fess/app/web/base/FessBaseAction.java

@@ -42,7 +42,6 @@ import org.dbflute.optional.OptionalThing;
 import org.lastaflute.db.dbflute.accesscontext.AccessContextArranger;
 import org.lastaflute.db.dbflute.accesscontext.AccessContextArranger;
 import org.lastaflute.web.TypicalAction;
 import org.lastaflute.web.TypicalAction;
 import org.lastaflute.web.callback.ActionRuntime;
 import org.lastaflute.web.callback.ActionRuntime;
-import org.lastaflute.web.login.LoginManager;
 import org.lastaflute.web.response.ActionResponse;
 import org.lastaflute.web.response.ActionResponse;
 import org.lastaflute.web.servlet.session.SessionManager;
 import org.lastaflute.web.servlet.session.SessionManager;
 import org.lastaflute.web.validation.ActionValidator;
 import org.lastaflute.web.validation.ActionValidator;
@@ -122,9 +121,7 @@ public abstract class FessBaseAction extends TypicalAction // has several interf
     //                                                                           =========
     //                                                                           =========
     @Override
     @Override
     protected OptionalThing<FessUserBean> getUserBean() { // to return as concrete class
     protected OptionalThing<FessUserBean> getUserBean() { // to return as concrete class
-        // #login waiting
-        //return fessLoginAssist.getSessionUserBean();
-        return OptionalThing.empty();// uses application server authentication so empty here
+        return fessLoginAssist.getSessionUserBean();
     }
     }
 
 
     @Override
     @Override
@@ -137,13 +134,6 @@ public abstract class FessBaseAction extends TypicalAction // has several interf
         return OptionalThing.of(USER_TYPE); // same reason as getUserBean()
         return OptionalThing.of(USER_TYPE); // same reason as getUserBean()
     }
     }
 
 
-    @Override
-    protected OptionalThing<LoginManager> myLoginManager() {
-        // #login waiting
-        //return OptionalThing.of(fessLoginAssist);
-        return OptionalThing.empty(); // same reason as getUserBean()
-    }
-
     // ===================================================================================
     // ===================================================================================
     //                                                                          Validation
     //                                                                          Validation
     //                                                                          ==========
     //                                                                          ==========

+ 7 - 0
src/main/java/org/codelibs/fess/app/web/base/FessSearchAction.java

@@ -43,7 +43,9 @@ import org.codelibs.fess.helper.SystemHelper;
 import org.codelibs.fess.helper.UserInfoHelper;
 import org.codelibs.fess.helper.UserInfoHelper;
 import org.codelibs.fess.helper.ViewHelper;
 import org.codelibs.fess.helper.ViewHelper;
 import org.codelibs.fess.screenshot.ScreenShotManager;
 import org.codelibs.fess.screenshot.ScreenShotManager;
+import org.dbflute.optional.OptionalThing;
 import org.lastaflute.web.callback.ActionRuntime;
 import org.lastaflute.web.callback.ActionRuntime;
+import org.lastaflute.web.login.LoginManager;
 import org.lastaflute.web.response.ActionResponse;
 import org.lastaflute.web.response.ActionResponse;
 import org.lastaflute.web.util.LaRequestUtil;
 import org.lastaflute.web.util.LaRequestUtil;
 
 
@@ -100,6 +102,11 @@ public abstract class FessSearchAction extends FessBaseAction {
         return super.hookBefore(runtime);
         return super.hookBefore(runtime);
     }
     }
 
 
+    @Override
+    protected OptionalThing<LoginManager> myLoginManager() {
+        return OptionalThing.empty();
+    }
+
     @Override
     @Override
     protected void setupHtmlData(final ActionRuntime runtime) {
     protected void setupHtmlData(final ActionRuntime runtime) {
         super.setupHtmlData(runtime);
         super.setupHtmlData(runtime);

+ 26 - 23
src/main/java/org/codelibs/fess/app/web/base/login/FessLoginAssist.java

@@ -17,6 +17,9 @@ package org.codelibs.fess.app.web.base.login;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 
 
+import org.codelibs.fess.app.web.login.LoginAction;
+import org.codelibs.fess.es.exbhv.UserBhv;
+import org.codelibs.fess.es.exentity.User;
 import org.codelibs.fess.mylasta.action.FessUserBean;
 import org.codelibs.fess.mylasta.action.FessUserBean;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.dbflute.optional.OptionalEntity;
 import org.dbflute.optional.OptionalEntity;
@@ -31,8 +34,9 @@ import org.lastaflute.web.login.option.LoginSpecifiedOption;
 
 
 /**
 /**
  * @author jflute
  * @author jflute
+ * @author shinsuke
  */
  */
-public class FessLoginAssist extends TypicalLoginAssist<String, FessUserBean, Object> // #change_it also UserBean
+public class FessLoginAssist extends TypicalLoginAssist<String, FessUserBean, User> // #change_it also UserBean
         implements LoginManager {
         implements LoginManager {
 
 
     // ===================================================================================
     // ===================================================================================
@@ -44,40 +48,41 @@ public class FessLoginAssist extends TypicalLoginAssist<String, FessUserBean, Ob
     private AsyncManager asyncManager;
     private AsyncManager asyncManager;
     @Resource
     @Resource
     private FessConfig fessConfig;
     private FessConfig fessConfig;
+    @Resource
+    private UserBhv userBhv;
 
 
     // ===================================================================================
     // ===================================================================================
     //                                                                           Find User
     //                                                                           Find User
     //                                                                           =========
     //                                                                           =========
     @Override
     @Override
-    protected boolean doCheckUserLoginable(final String email, final String cipheredPassword) {
-        //return memberBhv.selectCount(cb -> {
-        //    cb.query().arrangeLogin(email, cipheredPassword);
-        //}) > 0;
-        return false;
+    protected boolean doCheckUserLoginable(final String username, final String cipheredPassword) {
+        return userBhv.selectCount(cb -> {
+            cb.query().setName_Equal(username);
+            cb.query().setPassword_Equal(cipheredPassword);
+        }) > 0;
     }
     }
 
 
     @Override
     @Override
-    protected OptionalEntity<Object> doFindLoginUser(final String email, final String cipheredPassword) {
-        //return memberBhv.selectEntity(cb -> {
-        //    cb.query().arrangeLogin(email, cipheredPassword);
-        //});
-        return null;
+    protected OptionalEntity<User> doFindLoginUser(final String username, final String cipheredPassword) {
+        return userBhv.selectEntity(cb -> {
+            cb.query().setName_Equal(username);
+            cb.query().setPassword_Equal(cipheredPassword);
+        });
     }
     }
 
 
     @Override
     @Override
-    protected OptionalEntity<Object> doFindLoginUser(final String userId) {
-        //return memberBhv.selectEntity(cb -> {
-        //    cb.query().arrangeLoginByIdentity(userId);
-        //});
-        return null;
+    protected OptionalEntity<User> doFindLoginUser(final String username) {
+        return userBhv.selectEntity(cb -> {
+            cb.query().setName_Equal(username);
+        });
     }
     }
 
 
     // ===================================================================================
     // ===================================================================================
     //                                                                       Login Process
     //                                                                       Login Process
     //                                                                       =============
     //                                                                       =============
     @Override
     @Override
-    protected FessUserBean createUserBean(final Object userEntity) {
-        return new FessUserBean();
+    protected FessUserBean createUserBean(final User user) {
+        return new FessUserBean(user);
     }
     }
 
 
     @Override
     @Override
@@ -88,9 +93,9 @@ public class FessLoginAssist extends TypicalLoginAssist<String, FessUserBean, Ob
     }
     }
 
 
     @Override
     @Override
-    protected void saveLoginHistory(final Object member, final FessUserBean userBean, final LoginSpecifiedOption option) {
+    protected void saveLoginHistory(final User user, final FessUserBean userBean, final LoginSpecifiedOption option) {
         asyncManager.async(() -> {
         asyncManager.async(() -> {
-            insertLogin(member);
+            insertLogin(user);
         });
         });
     }
     }
 
 
@@ -112,8 +117,6 @@ public class FessLoginAssist extends TypicalLoginAssist<String, FessUserBean, Ob
 
 
     @Override
     @Override
     protected Class<?> getLoginActionType() {
     protected Class<?> getLoginActionType() {
-        // TODO
-        //        return LoginAction.class;
-        throw new UnsupportedOperationException("TODO");
+        return LoginAction.class;
     }
     }
 }
 }

+ 62 - 0
src/main/java/org/codelibs/fess/app/web/login/LoginAction.java

@@ -0,0 +1,62 @@
+/*
+ * Copyright 2009-2015 the 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.app.web.login;
+
+import org.codelibs.fess.app.web.admin.system.AdminSystemAction;
+import org.codelibs.fess.app.web.base.FessSearchAction;
+import org.lastaflute.web.Execute;
+import org.lastaflute.web.response.HtmlResponse;
+
+public class LoginAction extends FessSearchAction {
+
+    // ===================================================================================
+    //                                                                            Constant
+    //     
+
+    // ===================================================================================
+    //                                                                           Attribute
+    //     
+
+    // ===================================================================================
+    //                                                                               Hook
+    //                                                                              ======
+
+    // ===================================================================================
+    //                                                                      Search Execute
+    //                                                                      ==============
+
+    @Execute
+    public HtmlResponse index() {
+        return getHtmlResponse().useForm(LoginForm.class);
+    }
+
+    private HtmlResponse getHtmlResponse() {
+        return getUserBean().map(user -> redirect(AdminSystemAction.class)).orElse(asHtml(path_Login_IndexJsp));
+    }
+
+    @Execute
+    public HtmlResponse login(final LoginForm form) {
+        validate(form, messages -> {}, () -> {
+            form.clearSecurityInfo();
+            return asHtml(path_Login_IndexJsp);
+        });
+        String email = form.username;
+        String password = form.password;
+        return fessLoginAssist.loginRedirect(email, password, op -> {}, () -> getHtmlResponse());
+    }
+
+}

+ 19 - 0
src/main/java/org/codelibs/fess/app/web/login/LoginForm.java

@@ -0,0 +1,19 @@
+package org.codelibs.fess.app.web.login;
+
+import org.codelibs.fess.app.web.RootForm;
+import org.hibernate.validator.constraints.NotBlank;
+
+public class LoginForm extends RootForm {
+    private static final long serialVersionUID = 1L;
+
+    @NotBlank
+    public String username;
+
+    @NotBlank
+    public String password;
+
+    public void clearSecurityInfo() {
+        password = null;
+    }
+
+}

+ 48 - 0
src/main/java/org/codelibs/fess/app/web/logout/LogoutAction.java

@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009-2015 the 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.app.web.logout;
+
+import org.codelibs.fess.app.web.base.FessSearchAction;
+import org.codelibs.fess.app.web.login.LoginAction;
+import org.lastaflute.web.Execute;
+import org.lastaflute.web.response.HtmlResponse;
+
+public class LogoutAction extends FessSearchAction {
+
+    // ===================================================================================
+    //                                                                            Constant
+    //     
+
+    // ===================================================================================
+    //                                                                           Attribute
+    //     
+
+    // ===================================================================================
+    //                                                                               Hook
+    //                                                                              ======
+
+    // ===================================================================================
+    //                                                                      Search Execute
+    //                                                                      ==============
+
+    @Execute
+    public HtmlResponse index() {
+        fessLoginAssist.logout();
+        return redirect(LoginAction.class);
+    }
+
+}

+ 3 - 1
src/main/java/org/codelibs/fess/es/bsentity/AbstractEntity.java

@@ -176,7 +176,9 @@ public abstract class AbstractEntity implements Entity, Serializable, Cloneable
 
 
     public abstract Map<String, Object> toSource();
     public abstract Map<String, Object> toSource();
 
 
-    public class DocMeta {
+    public class DocMeta implements Serializable {
+
+        private static final long serialVersionUID = 1L;
 
 
         protected String id;
         protected String id;
 
 

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

@@ -383,9 +383,6 @@ public interface FessHtmlPath {
     /** The path of the HTML: /index.jsp */
     /** The path of the HTML: /index.jsp */
     HtmlNext path_IndexJsp = new HtmlNext("/index.jsp");
     HtmlNext path_IndexJsp = new HtmlNext("/index.jsp");
 
 
-    /** The path of the HTML: /login/error.jsp */
-    HtmlNext path_Login_ErrorJsp = new HtmlNext("/login/error.jsp");
-
     /** The path of the HTML: /login/footer.jsp */
     /** The path of the HTML: /login/footer.jsp */
     HtmlNext path_Login_FooterJsp = new HtmlNext("/login/footer.jsp");
     HtmlNext path_Login_FooterJsp = new HtmlNext("/login/footer.jsp");
 
 

+ 6 - 0
src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java

@@ -1442,6 +1442,9 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Reset */
     /** The key of the message: Reset */
     public static final String LABELS_crawling_session_reset = "{labels.crawling_session_reset}";
     public static final String LABELS_crawling_session_reset = "{labels.crawling_session_reset}";
 
 
+    /** The key of the message: List */
+    public static final String LABELS_crawling_session_link_list = "{labels.crawling_session_link_list}";
+
     /** The key of the message: Details */
     /** The key of the message: Details */
     public static final String LABELS_crawling_session_link_details = "{labels.crawling_session_link_details}";
     public static final String LABELS_crawling_session_link_details = "{labels.crawling_session_link_details}";
 
 
@@ -4983,6 +4986,9 @@ public class FessLabels extends ActionMessages {
         /** The key of the label: Reset */
         /** The key of the label: Reset */
         String LABELS_crawling_session_reset = "{labels.crawling_session_reset}";
         String LABELS_crawling_session_reset = "{labels.crawling_session_reset}";
 
 
+        /** The key of the label: List */
+        String LABELS_crawling_session_link_list = "{labels.crawling_session_link_list}";
+
         /** The key of the label: Details */
         /** The key of the label: Details */
         String LABELS_crawling_session_link_details = "{labels.crawling_session_link_details}";
         String LABELS_crawling_session_link_details = "{labels.crawling_session_link_details}";
 
 

+ 8 - 1
src/main/java/org/codelibs/fess/mylasta/action/FessUserBean.java

@@ -15,6 +15,7 @@
  */
  */
 package org.codelibs.fess.mylasta.action;
 package org.codelibs.fess.mylasta.action;
 
 
+import org.codelibs.fess.es.exentity.User;
 import org.lastaflute.web.login.TypicalUserBean;
 import org.lastaflute.web.login.TypicalUserBean;
 
 
 /**
 /**
@@ -27,6 +28,7 @@ public class FessUserBean extends TypicalUserBean<String> { // #change_it also L
     //                                                                          ==========
     //                                                                          ==========
     /** The serial version UID for object serialization. (Default) */
     /** The serial version UID for object serialization. (Default) */
     private static final long serialVersionUID = 1L;
     private static final long serialVersionUID = 1L;
+    private User user;
 
 
     // ===================================================================================
     // ===================================================================================
     //                                                                           Attribute
     //                                                                           Attribute
@@ -36,6 +38,11 @@ public class FessUserBean extends TypicalUserBean<String> { // #change_it also L
     //                                                                         Constructor
     //                                                                         Constructor
     //                                                                         ===========
     //                                                                         ===========
     public FessUserBean() {
     public FessUserBean() {
+        // TODO needed?
+    }
+
+    public FessUserBean(User user) {
+        this.user = user;
     }
     }
 
 
     // ===================================================================================
     // ===================================================================================
@@ -43,7 +50,7 @@ public class FessUserBean extends TypicalUserBean<String> { // #change_it also L
     //                                                                      ==============
     //                                                                      ==============
     @Override
     @Override
     public String getUserId() {
     public String getUserId() {
-        return null;
+        return user.getName();
     }
     }
 
 
     // ===================================================================================
     // ===================================================================================

+ 1 - 3
src/main/webapp/WEB-INF/view/common/admin2/header.jsp

@@ -20,11 +20,9 @@
               <li>
               <li>
                 <a href="${helpLink}" target="_olh"><i class="fa fa-question-circle"></i></a>
                 <a href="${helpLink}" target="_olh"><i class="fa fa-question-circle"></i></a>
               </li>
               </li>
-              <%-- TODO
               <li>
               <li>
-                <la:link href="${contextPath}/admin/logout"><i class="fa fa-sign-out"></i></la:link>
+                <a href="${contextPath}/logout"><i class="fa fa-sign-out"></i></a>
               </li>
               </li>
-              --%>
             </ul>
             </ul>
           </div>
           </div>
         </nav>
         </nav>

+ 0 - 1
src/main/webapp/WEB-INF/view/login/error.jsp

@@ -1 +0,0 @@
-<%org.codelibs.fess.crud.util.SAStrutsUtil.addSessionMessage(request, "error.login_error");%><c:redirect url="/login/login?msgs=error.login_error" />

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

@@ -2,7 +2,7 @@
 <div class="topbar">
 <div class="topbar">
 	<div class="fill">
 	<div class="fill">
 		<div class="container">
 		<div class="container">
-			<la:link styleClass="brand" href="/index"><la:message key="labels.header_brand_name"/></la:link>
+			<la:link styleClass="brand" href="/"><la:message key="labels.header_brand_name"/></la:link>
 		</div>
 		</div>
 	</div>
 	</div>
 </div>
 </div>

+ 15 - 18
src/main/webapp/WEB-INF/view/login/index.jsp

@@ -15,8 +15,7 @@
 	<jsp:include page="header.jsp" />
 	<jsp:include page="header.jsp" />
 	<div id="content-body" class="container">
 	<div id="content-body" class="container">
 		<div id="main" class="content" style="background-color:#fafafa;">
 		<div id="main" class="content" style="background-color:#fafafa;">
-			<form id="login" method="post"
-				action="<%=response.encodeURL("j_security_check")%>">
+			<la:form styleId="login" method="post">
 				<div class="row">
 				<div class="row">
 					<div class="modal" style="top:320px;">
 					<div class="modal" style="top:320px;">
 						<div class="modal-header">
 						<div class="modal-header">
@@ -26,45 +25,43 @@
 						</div>
 						</div>
 						<div class="modal-body">
 						<div class="modal-body">
 							<fieldset>
 							<fieldset>
-								<%
-									if ("error.login_error".equals(request.getParameter("msgs"))) {
-								%>
-								<div class="alert-message error">
-									<p>
-										<la:message key="error.login_error" />
-									</p>
+								<%-- Message --%>
+								<div>
+									<la:info id="msg" message="true">
+										<div class="alert-message info">
+											${msg}
+										</div>
+									</la:info>
+									<la:errors />
 								</div>
 								</div>
-								<%
-									}
-								%>
 								<div class="clearfix">
 								<div class="clearfix">
-									<label for="j_username"> <la:message
+									<label for="username"> <la:message
 											key="labels.user_name" />
 											key="labels.user_name" />
 									</label>
 									</label>
 									<div class="input">
 									<div class="input">
-										<input type="text" name="j_username" size="30" />
+										<la:text property="username" size="30" />
 									</div>
 									</div>
 								</div>
 								</div>
 								<div class="clearfix">
 								<div class="clearfix">
-									<label for="j_username"> <la:message
+									<label for="password"> <la:message
 											key="labels.password" />
 											key="labels.password" />
 									</label>
 									</label>
 									<div class="input">
 									<div class="input">
-										<input type="password" name="j_password" size="30" />
+										<la:password property="password" size="30" />
 									</div>
 									</div>
 								</div>
 								</div>
 							</fieldset>
 							</fieldset>
 						</div>
 						</div>
 						<div class="modal-footer">
 						<div class="modal-footer">
 							<div class="clearfix">
 							<div class="clearfix">
-								<input type="submit" name="loginButton"
+								<input type="submit" name="login"
 										value="<la:message key="labels.login"/>"
 										value="<la:message key="labels.login"/>"
 										class="btn small primary" />
 										class="btn small primary" />
 							</div>
 							</div>
 						</div>
 						</div>
 					</div>
 					</div>
 				</div>
 				</div>
-			</form>
+			</la:form>
 		</div>
 		</div>
 		<jsp:include page="footer.jsp" />
 		<jsp:include page="footer.jsp" />
 	</div>
 	</div>