package org.apereo.cas.web.flow;
import org.apereo.cas.logout.LogoutHttpMessage;
import org.apereo.cas.logout.LogoutManager;
import org.apereo.cas.logout.LogoutRequest;
import org.apereo.cas.logout.LogoutRequestStatus;
import org.apereo.cas.web.support.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.webflow.action.EventFactorySupport;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Logout action for front SLO : find the next eligible service and perform front logout.
*
* @author Jerome Leleu
* @since 4.0.0
*/
public class FrontChannelLogoutAction extends AbstractLogoutAction {
private static final Logger LOGGER = LoggerFactory.getLogger(FrontChannelLogoutAction.class);
private LogoutManager logoutManager;
/**
* Build from the logout manager.
*
* @param logoutManager a logout manager.
*/
public FrontChannelLogoutAction(final LogoutManager logoutManager) {
this.logoutManager = logoutManager;
}
@Override
protected Event doInternalExecute(final HttpServletRequest request, final HttpServletResponse response,
final RequestContext context) throws Exception {
final List<LogoutRequest> logoutRequests = WebUtils.getLogoutRequests(context);
final Map<LogoutRequest, LogoutHttpMessage> logoutUrls = new HashMap<>();
if (logoutRequests != null) {
logoutRequests.stream()
.filter(r -> r.getStatus() == LogoutRequestStatus.NOT_ATTEMPTED)
.forEach(r -> {
LOGGER.debug("Using logout url [{}] for front-channel logout requests", r.getLogoutUrl().toExternalForm());
final String logoutMessage = this.logoutManager.createFrontChannelLogoutMessage(r);
LOGGER.debug("Front-channel logout message to send is [{}]", logoutMessage);
final LogoutHttpMessage msg = new LogoutHttpMessage(r.getLogoutUrl(), logoutMessage, true);
logoutUrls.put(r, msg);
r.setStatus(LogoutRequestStatus.SUCCESS);
r.getService().setLoggedOutAlready(true);
});
if (!logoutUrls.isEmpty()) {
context.getFlowScope().put("logoutUrls", logoutUrls);
return new EventFactorySupport().event(this, "propagate");
}
}
return new EventFactorySupport().event(this, FINISH_EVENT);
}
}