Browse Source

#2469 improve logout process

Shinsuke Sugaya 5 years ago
parent
commit
265138862c

+ 35 - 8
src/main/java/org/codelibs/fess/app/web/sso/SsoAction.java

@@ -21,6 +21,7 @@ import org.codelibs.fess.app.web.RootAction;
 import org.codelibs.fess.app.web.base.FessLoginAction;
 import org.codelibs.fess.app.web.base.login.ActionResponseCredential;
 import org.codelibs.fess.app.web.login.LoginAction;
+import org.codelibs.fess.exception.SsoMessageException;
 import org.codelibs.fess.sso.SsoManager;
 import org.codelibs.fess.sso.SsoResponseType;
 import org.codelibs.fess.util.ComponentUtil;
@@ -79,20 +80,46 @@ public class SsoAction extends FessLoginAction {
     @Execute
     public ActionResponse metadata() {
         final SsoManager ssoManager = ComponentUtil.getSsoManager();
-        final ActionResponse actionResponse = ssoManager.getResponse(SsoResponseType.METADATA);
-        if (actionResponse == null) {
-            throw responseManager.new400("Unsupported request type.");
+        try {
+            final ActionResponse actionResponse = ssoManager.getResponse(SsoResponseType.METADATA);
+            if (actionResponse == null) {
+                throw responseManager.new400("Unsupported request type.");
+            }
+            return actionResponse;
+        } catch (final SsoMessageException e) {
+            if (e.getCause() == null) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Metadata response.", e);
+                }
+                saveInfo(e.getMessageCode());
+            } else {
+                logger.warn("Failed to process metadata.", e);
+                saveError(e.getMessageCode());
+            }
+            return redirect(LoginAction.class);
         }
-        return actionResponse;
     }
 
     @Execute
     public ActionResponse logout() {
         final SsoManager ssoManager = ComponentUtil.getSsoManager();
-        final ActionResponse actionResponse = ssoManager.getResponse(SsoResponseType.LOGOUT);
-        if (actionResponse == null) {
-            throw responseManager.new400("Unsupported request type.");
+        try {
+            final ActionResponse actionResponse = ssoManager.getResponse(SsoResponseType.LOGOUT);
+            if (actionResponse == null) {
+                throw responseManager.new400("Unsupported request type.");
+            }
+            return actionResponse;
+        } catch (final SsoMessageException e) {
+            if (e.getCause() == null) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Logout response.", e);
+                }
+                saveInfo(e.getMessageCode());
+            } else {
+                logger.warn("Failed to log out.", e);
+                saveError(e.getMessageCode());
+            }
+            return redirect(LoginAction.class);
         }
-        return actionResponse;
     }
 }

+ 44 - 0
src/main/java/org/codelibs/fess/exception/SsoMessageException.java

@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2020 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;
+
+import org.codelibs.fess.mylasta.action.FessMessages;
+import org.lastaflute.web.validation.VaMessenger;
+
+public class SsoMessageException extends FessSystemException {
+
+    private static final long serialVersionUID = 1L;
+
+    private transient final VaMessenger<FessMessages> messageCode;
+
+    public SsoMessageException(final VaMessenger<FessMessages> messageCode, final String message, final Throwable cause) {
+        super(message, cause);
+        this.messageCode = messageCode;
+    }
+
+    public SsoMessageException(final VaMessenger<FessMessages> messageCode, final String message) {
+        super(message);
+        this.messageCode = messageCode;
+    }
+
+    /**
+     * @return the messageCode
+     */
+    public VaMessenger<FessMessages> getMessageCode() {
+        return messageCode;
+    }
+
+}

+ 30 - 0
src/main/java/org/codelibs/fess/exception/SsoProcessException.java

@@ -0,0 +1,30 @@
+/*
+ * Copyright 2012-2020 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 SsoProcessException extends FessSystemException {
+
+    private static final long serialVersionUID = 1L;
+
+    public SsoProcessException(final String message) {
+        super(message);
+    }
+
+    public SsoProcessException(final String message, final Exception e) {
+        super(message, e);
+    }
+
+}

+ 35 - 0
src/main/java/org/codelibs/fess/mylasta/action/FessMessages.java

@@ -353,6 +353,9 @@ public class FessMessages extends FessLabels {
     /** The key of the message: Failed to install {0}. */
     public static final String ERRORS_failed_to_install_plugin = "{errors.failed_to_install_plugin}";
 
+    /** The key of the message: Failed to process the request: {0} */
+    public static final String ERRORS_failed_to_process_sso_request = "{errors.failed_to_process_sso_request}";
+
     /** The key of the message: The given query has unknown condition. */
     public static final String ERRORS_invalid_query_unknown = "{errors.invalid_query_unknown}";
 
@@ -509,6 +512,9 @@ public class FessMessages extends FessLabels {
     /** The key of the message: Uploaded {0} */
     public static final String SUCCESS_upload_file_to_storage = "{success.upload_file_to_storage}";
 
+    /** The key of the message: Logged out. */
+    public static final String SUCCESS_sso_logout = "{success.sso_logout}";
+
     /** The key of the message: Created data. */
     public static final String SUCCESS_crud_create_crud_table = "{success.crud_create_crud_table}";
 
@@ -2091,6 +2097,21 @@ public class FessMessages extends FessLabels {
         return this;
     }
 
+    /**
+     * Add the created action message for the key 'errors.failed_to_process_sso_request' with parameters.
+     * <pre>
+     * message: Failed to process the request: {0}
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @param arg0 The parameter arg0 for message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsFailedToProcessSsoRequest(String property, String arg0) {
+        assertPropertyNotNull(property);
+        add(property, new UserMessage(ERRORS_failed_to_process_sso_request, arg0));
+        return this;
+    }
+
     /**
      * Add the created action message for the key 'errors.invalid_query_unknown' with parameters.
      * <pre>
@@ -2846,6 +2867,20 @@ public class FessMessages extends FessLabels {
         return this;
     }
 
+    /**
+     * Add the created action message for the key 'success.sso_logout' with parameters.
+     * <pre>
+     * message: Logged out.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addSuccessSsoLogout(String property) {
+        assertPropertyNotNull(property);
+        add(property, new UserMessage(SUCCESS_sso_logout));
+        return this;
+    }
+
     /**
      * Add the created action message for the key 'success.crud_create_crud_table' with parameters.
      * <pre>

+ 31 - 20
src/main/java/org/codelibs/fess/sso/saml/SamlAuthenticator.java

@@ -37,11 +37,14 @@ import org.codelibs.fess.app.web.base.login.SamlCredential;
 import org.codelibs.fess.app.web.base.login.SamlCredential.SamlUser;
 import org.codelibs.fess.crawler.Constants;
 import org.codelibs.fess.exception.SsoLoginException;
+import org.codelibs.fess.exception.SsoMessageException;
+import org.codelibs.fess.exception.SsoProcessException;
 import org.codelibs.fess.mylasta.action.FessUserBean;
 import org.codelibs.fess.sso.SsoAuthenticator;
 import org.codelibs.fess.sso.SsoResponseType;
 import org.codelibs.fess.util.ComponentUtil;
 import org.dbflute.optional.OptionalEntity;
+import org.lastaflute.core.message.UserMessages;
 import org.lastaflute.web.login.credential.LoginCredential;
 import org.lastaflute.web.response.ActionResponse;
 import org.lastaflute.web.response.HtmlResponse;
@@ -242,18 +245,25 @@ public class SamlAuthenticator implements SsoAuthenticator {
                                 }
                             });
                         } else {
-                            return getStreamResponse("metadata", "text/html; charset=UTF-8", errors.stream().map(s -> "<p>" + s + "</p>")
-                                    .collect(Collectors.joining()));
+                            final String msg = errors.stream().collect(Collectors.joining(", "));
+                            throw new SsoMessageException(messages -> messages.addErrorsFailedToProcessSsoRequest(
+                                    UserMessages.GLOBAL_PROPERTY_KEY, msg), "Failed to log out.", new SsoProcessException(msg));
                         }
+                    } catch (final SsoMessageException e) {
+                        throw e;
                     } catch (final Exception e) {
-                        logger.warn("Failed to process metadata.", e);
-                        return getStreamResponse("metadata", "text/html; charset=UTF-8", e.getMessage());
+                        throw new SsoMessageException(messages -> messages.addErrorsFailedToProcessSsoRequest(
+                                UserMessages.GLOBAL_PROPERTY_KEY, e.getMessage()), "Failed to process metadata.", e);
                     }
-                }).orElseGet(() -> getStreamResponse("metadata", "text/html; charset=UTF-8", "Invalid state."));
+                })
+                .orElseThrow(
+                        () -> new SsoMessageException(messages -> messages.addErrorsFailedToProcessSsoRequest(
+                                UserMessages.GLOBAL_PROPERTY_KEY, "Invalid state."), "Failed to process metadata.",
+                                new SsoProcessException("Invalid state.")));
     }
 
     protected ActionResponse getLogoutResponse() {
-        return LaRequestUtil
+        LaRequestUtil
                 .getOptionalRequest()
                 .map(request -> {
                     if (logger.isDebugEnabled()) {
@@ -265,23 +275,24 @@ public class SamlAuthenticator implements SsoAuthenticator {
                         auth.processSLO();
                         final List<String> errors = auth.getErrors();
                         if (errors.isEmpty()) {
-                            return getStreamResponse("logout", "text/html; charset=UTF-8", "Logged out");
+                            throw new SsoMessageException(messages -> messages.addSuccessSsoLogout(UserMessages.GLOBAL_PROPERTY_KEY),
+                                    "Logged out");
                         } else {
-                            return getStreamResponse("logout", "text/html; charset=UTF-8", errors.stream().map(s -> "<p>" + s + "</p>")
-                                    .collect(Collectors.joining()));
+                            final String msg = errors.stream().collect(Collectors.joining(", "));
+                            throw new SsoMessageException(messages -> messages.addErrorsFailedToProcessSsoRequest(
+                                    UserMessages.GLOBAL_PROPERTY_KEY, msg), "Failed to log out.", new SsoProcessException(msg));
                         }
+                    } catch (final SsoMessageException e) {
+                        throw e;
                     } catch (final Exception e) {
-                        logger.warn("Failed to process logout.", e);
-                        return getStreamResponse("metadata", "text/html; charset=UTF-8", e.getMessage());
+                        throw new SsoMessageException(messages -> messages.addErrorsFailedToProcessSsoRequest(
+                                UserMessages.GLOBAL_PROPERTY_KEY, e.getMessage()), "Failed to log out.", e);
                     }
-                }).orElseGet(() -> getStreamResponse("metadata", "text/html; charset=UTF-8", "Invalid state."));
-    }
-
-    protected StreamResponse getStreamResponse(final String filename, final String contentType, final String content) {
-        return new StreamResponse(filename).contentType(contentType).stream(out -> {
-            try (final Writer writer = new OutputStreamWriter(out.stream(), Constants.UTF_8_CHARSET)) {
-                writer.write(content);
-            }
-        });
+                })
+                .orElseThrow(
+                        () -> new SsoMessageException(messages -> messages.addErrorsFailedToProcessSsoRequest(
+                                UserMessages.GLOBAL_PROPERTY_KEY, "Invalid state."), "Failed to log out.", new SsoProcessException(
+                                "Invalid state.")));
+        return null;
     }
 }

+ 2 - 0
src/main/resources/fess_message.properties

@@ -139,6 +139,7 @@ errors.failed_to_print_thread_dump=Failed to print thread dump.
 errors.file_is_not_supported={0} is not supported.
 errors.plugin_file_is_not_found={0} is not found.
 errors.failed_to_install_plugin=Failed to install {0}.
+errors.failed_to_process_sso_request=Failed to process the request: {0}
 
 errors.invalid_query_unknown=The given query has unknown condition.
 errors.invalid_query_parse_error=The given query is invalid.
@@ -196,6 +197,7 @@ success.print_thread_dump=Printed thread dump to log file.
 success.install_plugin=Installing {0} plugin.
 success.delete_plugin=Deleting {0} plugin.
 success.upload_file_to_storage=Uploaded {0}
+success.sso_logout=Logged out.
 
 success.crud_create_crud_table=Created data.
 success.crud_update_crud_table=Updated data.

+ 2 - 0
src/main/resources/fess_message_en.properties

@@ -135,6 +135,7 @@ errors.failed_to_print_thread_dump=Failed to print thread dump.
 errors.file_is_not_supported={0} is not supported.
 errors.plugin_file_is_not_found={0} is not found.
 errors.failed_to_install_plugin=Failed to install {0}.
+errors.failed_to_process_sso_request=Failed to process the request: {0}
 
 errors.invalid_query_unknown=The given query has unknown condition.
 errors.invalid_query_parse_error=The given query is invalid.
@@ -192,6 +193,7 @@ success.print_thread_dump=Printed thread dump to log file.
 success.install_plugin=Installing {0} plugin.
 success.delete_plugin=Deleting {0} plugin.
 success.upload_file_to_storage=Uploaded {0}
+success.sso_logout=Logged out.
 
 success.crud_create_crud_table=Created data.
 success.crud_update_crud_table=Updated data.

+ 2 - 0
src/main/resources/fess_message_ja.properties

@@ -141,6 +141,7 @@ errors.failed_to_print_thread_dump=スレッドダンプの出力に失敗しま
 errors.file_is_not_supported={0}はサポートされていません。
 errors.plugin_file_is_not_found={0}が見つかりません。
 errors.failed_to_install_plugin={0}のインストールに失敗しました。
+errors.failed_to_process_sso_request=リクエストの処理に失敗しました: {0}
 
 errors.property_required={0}は必須です。
 errors.property_type_integer={0}は数値です。
@@ -185,6 +186,7 @@ success.print_thread_dump=スレッドダンプをログファイルに出力し
 success.install_plugin=プラグイン {0} をインストールしています。
 success.delete_plugin=プラグイン {0} を削除しています。
 success.upload_file_to_storage={0} をアップロードしました。
+success.sso_logout=ログアウトしました。
 
 success.crud_create_crud_table = データを作成しました。
 success.crud_update_crud_table = データを更新しました。