#2469 improve logout process

This commit is contained in:
Shinsuke Sugaya 2020-07-06 06:44:59 +09:00
parent d4a16f872e
commit 265138862c
8 changed files with 181 additions and 28 deletions

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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>

View file

@ -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;
}
}

View file

@ -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.

View file

@ -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.

View file

@ -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 = データを更新しました。