Skip to content

Commit

Permalink
Show error page with timestampt on oxauth error
Browse files Browse the repository at this point in the history
  • Loading branch information
yurem committed Jan 6, 2017
1 parent 769ab92 commit 7cb43d4
Show file tree
Hide file tree
Showing 5 changed files with 303 additions and 0 deletions.
4 changes: 4 additions & 0 deletions oxService/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -202,5 +202,9 @@
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
</dependency>
</dependencies>
</project>
160 changes: 160 additions & 0 deletions oxService/src/main/java/org/xdi/facelet/CustomRendererRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package org.xdi.facelet;

import java.io.IOException;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

import org.jboss.seam.core.ResourceLoader;
import org.jboss.seam.jsf.DelegatingFacesContext;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.jboss.seam.mock.MockHttpServletRequest;
import org.jboss.seam.mock.MockHttpServletResponse;
import org.jboss.seam.ui.facelet.HttpSessionManager;
import org.jboss.seam.ui.facelet.RendererFacesContextFactory;
import org.jboss.seam.ui.util.JSF;

import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.facelets.Facelet;

public class CustomRendererRequest
{
private static final LogProvider log = Logging.getLogProvider(CustomRendererRequest.class);

private FacesContext originalFacesContext;
private FacesContext facesContext;

private MockHttpServletRequest request;
private MockHttpServletResponse response;

private StringWriter writer;

private String viewId;

private ClassLoader originalClassLoader;

public CustomRendererRequest(String viewId)
{
this.viewId = viewId;
}

public void init()
{
if (FacesContext.getCurrentInstance() != null) {
request = new MockHttpServletRequest(HttpSessionManager.instance(), FacesContext.getCurrentInstance().getExternalContext());
} else {
request = new MockHttpServletRequest(HttpSessionManager.instance());
}
response = new MockHttpServletResponse();

setContextClassLoader();

// Generate the FacesContext from the JSF FacesContextFactory
originalFacesContext = FacesContext.getCurrentInstance();
facesContext = RendererFacesContextFactory.instance().getFacesContext(request, response);
DelegatingFacesContext.setCurrentInstance(facesContext);

// Copy request paramers from original context
Map<String, Object> requestMap = originalFacesContext.getExternalContext().getRequestMap();
for (String requestParameterKey : requestMap.keySet()) {
facesContext.getExternalContext().getRequestMap().put(requestParameterKey, requestMap.get(requestParameterKey));
}

// Copy messages from original context
for (Iterator<String> clientIt = originalFacesContext.getClientIdsWithMessages(); clientIt.hasNext();) {
String clientId = clientIt.next();
for (Iterator<FacesMessage> messagesIt = originalFacesContext.getMessages(clientId); messagesIt.hasNext();) {
FacesMessage message = messagesIt.next();
facesContext.addMessage(clientId, message);
}
}

// Create the viewRoot
UIViewRoot newRoot = facesContext.getApplication().getViewHandler().createView(facesContext, viewId);
facesContext.setViewRoot(newRoot);

// Set the responseWriter to write to a buffer
writer = new StringWriter();
facesContext.setResponseWriter(facesContext.getRenderKit().createResponseWriter(writer,
null, null));
}

private void cleanup()
{
facesContext.release();
DelegatingFacesContext.setCurrentInstance(originalFacesContext);

originalFacesContext = null;
facesContext = null;
request = null;
response = null;
}

protected void setContextClassLoader() {
// JBSEAM-3555 Quick fix
// Set the context classloader to the cached one
originalClassLoader = Thread.currentThread().getContextClassLoader();
ServletContext ctx = request.getSession().getServletContext();
WeakReference<ClassLoader> ref = (WeakReference<ClassLoader>)ctx.getAttribute("seam.context.classLoader");
if (ref == null || ref.get() == null) {
log.warn("Failed to bootstrap context classloader. Facelets may not work properly from MDBs");
} else {
Thread.currentThread().setContextClassLoader(ref.get());
}
}

protected void resetContextClassLoader() {
// JBSEAM-3555 Quick fix
if (originalClassLoader != null) {
Thread.currentThread().setContextClassLoader(originalClassLoader);
originalClassLoader = null;
}
}

public void run() throws IOException
{
try {
init();
renderFacelet(facesContext, faceletForViewId(viewId));
} finally {
cleanup();
resetContextClassLoader();
}
}

public String getOutput()
{
return writer.getBuffer().toString();
}

/**
* Get a Facelet for a URL
*/
protected Facelet faceletForViewId(String viewId) throws IOException
{
URL url = ResourceLoader.instance().getResource(viewId);
if (url == null)
{
throw new IllegalArgumentException("resource doesn't exist: " + viewId);
}
return ApplicationAssociate.getCurrentInstance().getFaceletFactory().getFacelet(url);
}

/**
* Render a Facelet
*/
protected void renderFacelet(FacesContext facesContext, Facelet facelet) throws IOException
{
UIViewRoot root = facesContext.getViewRoot();
facelet.apply(facesContext, root);
JSF.renderChildren(facesContext, root);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.xdi.service.exception;

import java.io.IOException;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.io.IOUtils;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.Events;
import org.jboss.seam.core.Interpolator;
import org.jboss.seam.exception.Exceptions;
import org.jboss.seam.util.Strings;
import org.xdi.facelet.CustomRendererRequest;

/**
* Allows to extends the exception handler chain
*
* @author Yuriy Movchan
* @version January 05, 2017
*/
@Scope(ScopeType.APPLICATION)
@BypassInterceptors
@Install(precedence = Install.APPLICATION, classDependencies = "javax.faces.context.FacesContext")
@Name("org.jboss.seam.exception.exceptions")
public class GluuCustomExceptions extends Exceptions {

public void handle(Exception e) throws Exception {
if (handleServiceException(e)) {
Events.instance().raiseEvent("org.jboss.seam.exceptionHandled." + e.getClass().getName(), e);
Events.instance().raiseEvent("org.jboss.seam.exceptionHandled", e);
return;
}

super.handle(e);
}

public static Exceptions instance() {
if (!Contexts.isApplicationContextActive()) {
throw new IllegalStateException("No active application context");
}

return (Exceptions) Component.getInstance(GluuCustomExceptions.class, ScopeType.APPLICATION);
}

public boolean handleServiceException(Exception ex) throws IOException {
FacesContext ctx = FacesContext.getCurrentInstance();
if (ctx == null) {
return false;
}

String servletPath = ctx.getExternalContext().getRequestServletPath();
if (!servletPath.startsWith("/seam/resource")) {
return false;
}

addErrorMessage(null, ex);

final HttpServletResponse httpResponse = (HttpServletResponse) ctx.getExternalContext().getResponse();

CustomRendererRequest customRendererRequest = new CustomRendererRequest("/error_service.xhtml");
customRendererRequest.run();
String errorPage = customRendererRequest.getOutput();

httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0.
httpResponse.setHeader("Expires", "0"); // Proxies.

httpResponse.setContentType("text/html;charset=UTF-8");
httpResponse.setStatus(HttpStatus.SC_BAD_REQUEST);

IOUtils.write(errorPage, httpResponse.getOutputStream());

return true;
}

protected void addErrorMessage(String message, Exception ex) {
if (Contexts.isConversationContextActive()) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
getDisplayMessage(ex, null), "An unexpected error has occurred."));
}
}

protected String getDisplayMessage(Exception ex, String message) {
if (Strings.isEmpty(message) && (ex.getMessage() != null)) {
return ex.getMessage();
} else {
return Interpolator.instance().interpolate(message, ex);
}
}
}
35 changes: 35 additions & 0 deletions oxService/src/main/java/org/xdi/service/util/PageService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.xdi.service.util;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

/**
* Created by eugeniuparvan on 12/22/16.
*
* @author Yuriy Movchan
*/
@Name("pageService")
@Scope(ScopeType.STATELESS)
@AutoCreate
public class PageService {

private static final DateFormat currentDateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");

public String getRootUrlByRequest(HttpServletRequest request) {
String url = request.getRequestURL().toString();
return url.substring(0, url.length() - request.getRequestURI().length());
}

public String getCurrentDateTime() {
return currentDateTimeFormatter.format(new Date());
}

}
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@
<artifactId>jsf-api</artifactId>
<version>2.1.28</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.28-jbossorg-1</version>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down

0 comments on commit 7cb43d4

Please sign in to comment.