Skip to content

Commit

Permalink
mandatory applicationPath, http error handling and reference library …
Browse files Browse the repository at this point in the history
…reorg
  • Loading branch information
jrivard committed Nov 6, 2015
1 parent d4f4fe4 commit 41d74e3
Show file tree
Hide file tree
Showing 38 changed files with 1,044 additions and 552 deletions.
32 changes: 18 additions & 14 deletions src/main/java/password/pwm/PwmApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,24 @@ private void initialize()
pwmServiceManager.initAllServices();

if (!pwmEnvironment.isInternalRuntimeInstance()) {
final TimeDuration totalTime = TimeDuration.fromCurrent(startTime);
LOGGER.info(PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " open for bidness! (" + totalTime.asCompactString() + ")");
StatisticsManager.incrementStat(this,Statistic.PWM_STARTUPS);
LOGGER.debug("buildTime=" + PwmConstants.BUILD_TIME + ", javaLocale=" + Locale.getDefault() + ", DefaultLocale=" + PwmConstants.DEFAULT_LOCALE);

final Thread postInitThread = new Thread() {
@Override
public void run() {
postInitTasks();
}
};
postInitThread.setDaemon(true);
postInitThread.setName(Helper.makeThreadName(this, PwmApplication.class));
postInitThread.start();
if (pwmEnvironment.getFlags().contains(PwmEnvironment.ApplicationFlag.CommandLineInstance)) {
postInitTasks();
} else {
final TimeDuration totalTime = TimeDuration.fromCurrent(startTime);
LOGGER.info(PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " open for bidness! (" + totalTime.asCompactString() + ")");
StatisticsManager.incrementStat(this, Statistic.PWM_STARTUPS);
LOGGER.debug("buildTime=" + PwmConstants.BUILD_TIME + ", javaLocale=" + Locale.getDefault() + ", DefaultLocale=" + PwmConstants.DEFAULT_LOCALE);

final Thread postInitThread = new Thread() {
@Override
public void run() {
postInitTasks();
}
};
postInitThread.setDaemon(true);
postInitThread.setName(Helper.makeThreadName(this, PwmApplication.class));
postInitThread.start();
}
}
}

Expand Down
19 changes: 13 additions & 6 deletions src/main/java/password/pwm/PwmConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,14 @@

import org.apache.commons.csv.CSVFormat;
import password.pwm.bean.SessionLabel;
import password.pwm.util.JsonUtil;
import password.pwm.util.secure.PwmBlockAlgorithm;
import password.pwm.util.secure.PwmHashAlgorithm;

import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.TimeZone;
import java.util.*;

/**
* Constant values used throughout the servlet.
Expand Down Expand Up @@ -183,10 +181,19 @@ public enum REQUEST_ATTR {
public static final String DOWNLOAD_FILENAME_USER_REPORT_RECORDS_CSV = "UserReportRecords.csv";
public static final String DOWNLOAD_FILENAME_AUDIT_RECORDS_CSV = "AuditRecords.csv";

public static final String DEFAULT_BUILD_CHECKSUM_FILENAME = "BuildChecksum.properties";

public static final String LOG_REMOVED_VALUE_REPLACEMENT = readPwmConstantsBundle("log.removedValue");

public static final Collection<Locale> INCLUDED_LOCALES;
static {
final List<Locale> localeList = new ArrayList<>();
final String inputString = readPwmConstantsBundle("includedLocales");
final List<String> inputList = JsonUtil.deserializeStringList(inputString);
for (final String localeKey : inputList) {
localeList.add(new Locale(localeKey));
}
INCLUDED_LOCALES = Collections.unmodifiableCollection(localeList);
}

public enum JSP_URL {

INIT("init.jsp"),
Expand Down
1 change: 1 addition & 0 deletions src/main/java/password/pwm/PwmEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public enum ApplicationFlag {
Appliance,
ManageHttps,
NoFileLock,
CommandLineInstance,

;

Expand Down
1 change: 1 addition & 0 deletions src/main/java/password/pwm/error/PwmError.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public enum PwmError {
ERROR_MACRO_PARSE_ERROR("Error_MacroParseError",5080,true),
ERROR_NO_PROFILE_ASSIGNED("Error_NoProfileAssigned",5081,true),
ERROR_STARTUP_ERROR("Error_StartupError",5082,true),
ERROR_ENVIRONMENT_ERROR("Error_EnvironmentError",5083,true),

ERROR_REMOTE_ERROR_VALUE("Error_RemoteErrorValue",6000,true),

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/password/pwm/health/LDAPStatusChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ private static List<HealthRecord> checkUserPermissionValues(final PwmApplication
try {
returnList.addAll(checkUserPermission(pwmApplication, userPermission, pwmSetting));
} catch (PwmUnrecoverableException e) {
LOGGER.error(e.getMessage(),e);
LOGGER.error("error checking configured permission settings:" + e.getMessage());
}
}
}
Expand Down
40 changes: 1 addition & 39 deletions src/main/java/password/pwm/http/ContextManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.*;

public class ContextManager implements Serializable {
Expand Down Expand Up @@ -148,11 +147,8 @@ public void initialize() {
{
final String applicationPathStr = readApplicationPath();
if (applicationPathStr == null || applicationPathStr.isEmpty()) {
applicationPath = locateWebInfFilePath();
/*
startupErrorInformation = new ErrorInformation(PwmError.ERROR_STARTUP_ERROR,"applicationPath is not specified");
startupErrorInformation = new ErrorInformation(PwmError.ERROR_ENVIRONMENT_ERROR,"application path is not specified");
return;
*/
} else {
applicationPath = new File(applicationPathStr);
}
Expand Down Expand Up @@ -434,40 +430,6 @@ public Collection<PwmEnvironment.ApplicationFlag> readApplicationFlags() {
}
}

public File deriveApplicationPath()
throws PwmException
{
if (this.servletContext == null) {
return null;
}

final String realPath = servletContext.getRealPath("/WEB-INF");

if (realPath != null) {
final File servletPath = new File(realPath);
if (servletPath.exists()) {
return servletPath;
}
}

outputError("servlet container unable to return real file system path, will attempt discovery using classloader");

// for containers which do not return the real path, try to use the class loader to find the path.
final String cManagerName = PwmApplication.class.getCanonicalName();
final String resourcePathname = "/" + cManagerName.replace(".", "/") + ".class";
final URL fileURL = PwmApplication.class.getResource(resourcePathname);
if (fileURL != null) {
final String newString = fileURL.toString().replace("WEB-INF/classes" + resourcePathname, "");
try {
return new File(new URL(newString).toURI());
} catch (Exception e) {
outputError("unable to determine application path using class loader: " + e.getMessage());
}
}

throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_APP_UNAVAILABLE,"unable to determine applicationPath working directory"));
}

static void outputError(String outputText) {
final String msg = PwmConstants.PWM_APP_NAME + " " + PwmConstants.DEFAULT_DATETIME_FORMAT.format(new Date()) + " " + outputText;
System.out.println(msg);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/password/pwm/http/PwmURL.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public boolean isLoginServlet() {
}

public boolean isResourceURL() {
return checkIfStartsWithURL("/public/resources/");
return checkIfStartsWithURL("/public/resources/") || isReferenceURL();
}

public boolean isReferenceURL() {
Expand Down
26 changes: 18 additions & 8 deletions src/main/java/password/pwm/http/filter/AbstractPwmFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
package password.pwm.http.filter;


import password.pwm.bean.SessionLabel;
import password.pwm.error.PwmException;
import password.pwm.http.PwmRequest;
import password.pwm.http.PwmURL;
import password.pwm.util.logging.PwmLogger;

import javax.servlet.*;
Expand Down Expand Up @@ -53,18 +53,28 @@ public void doFilter(
final HttpServletRequest req = (HttpServletRequest)servletRequest;
final HttpServletResponse resp = (HttpServletResponse)servletResponse;

final PwmFilterChain pwmFilterChain = new PwmFilterChain(servletRequest, servletResponse, filterChain);

SessionLabel sessionLabel = null;
PwmRequest pwmRequest = null;
try {
final PwmRequest pwmRequest = PwmRequest.forRequest(req,resp);
sessionLabel = pwmRequest.getSessionLabel();
pwmRequest = PwmRequest.forRequest(req, resp);
} catch (PwmException e) {
final PwmURL pwmURL = new PwmURL(req);
if (pwmURL.isResourceURL()) {
filterChain.doFilter(req,resp);
return;
}

LOGGER.error(pwmRequest, "unexpected error processing filter chain: " + e.getMessage(), e);
}

try {
final PwmFilterChain pwmFilterChain = new PwmFilterChain(servletRequest, servletResponse, filterChain);
processFilter(pwmRequest, pwmFilterChain);
} catch (PwmException e) {
LOGGER.error(sessionLabel, "unexpected error processing filter chain: " + e.getMessage(), e);
LOGGER.error(pwmRequest, "unexpected error processing filter chain: " + e.getMessage(), e);
} catch (IOException e) {
LOGGER.debug(sessionLabel, "i/o error processing request: " + e.getMessage());
LOGGER.debug(pwmRequest, "i/o error processing request: " + e.getMessage());
}

}

abstract void processFilter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import password.pwm.PwmConstants;
import password.pwm.error.ErrorInformation;
import password.pwm.http.ContextManager;
import password.pwm.http.PwmURL;
import password.pwm.util.logging.PwmLogger;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

Expand All @@ -20,6 +22,7 @@ public void init(FilterConfig filterConfig) throws ServletException {

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

ErrorInformation startupError = null;
try {
final ServletContext servletContext = servletRequest.getServletContext();
Expand All @@ -34,12 +37,18 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
}
}
} catch (Exception e) {
final PwmURL pwmURL = new PwmURL((HttpServletRequest)servletRequest);
if (pwmURL.isResourceURL()) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}

LOGGER.error("error while trying to detect application status: " + e.getMessage());
}

LOGGER.error("unable to satisfy incoming request, application is not available");
servletRequest.setAttribute(PwmConstants.REQUEST_ATTR.PwmErrorInfo.toString(), startupError);
((HttpServletResponse)servletResponse).setStatus(500);
((HttpServletResponse) servletResponse).setStatus(500);
final String url = PwmConstants.JSP_URL.APP_UNAVAILABLE.getPath();
servletRequest.getServletContext().getRequestDispatcher(url).forward(servletRequest, servletResponse);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,12 @@ public void doFilter(
final HttpServletResponse resp = (HttpServletResponse)servletResponse;

try {
//if (!(new PwmURL(req).isResourceURL())) {
final PwmURL pwmURL = new PwmURL(req);
if (!pwmURL.isResourceURL()) {
checkAndInitSessionState(req);
final PwmRequest pwmRequest = PwmRequest.forRequest(req,resp);
checkIfSessionRecycleNeeded(pwmRequest);
//}
}
} catch (Throwable e) {
LOGGER.error("can't load application: " + e.getMessage(),e);
if (!(new PwmURL(req).isResourceURL())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

package password.pwm.http.servlet.resource;

import com.novell.ldapchai.exception.ChaiUnavailableException;
import org.apache.commons.io.IOUtils;
import password.pwm.PwmApplication;
import password.pwm.PwmConstants;
Expand All @@ -33,7 +32,7 @@
import password.pwm.http.HttpMethod;
import password.pwm.http.PwmRequest;
import password.pwm.http.ServletHelper;
import password.pwm.http.servlet.AbstractPwmServlet;
import password.pwm.http.servlet.PwmServlet;
import password.pwm.svc.stats.EventRateMeter;
import password.pwm.svc.stats.Statistic;
import password.pwm.svc.stats.StatisticsManager;
Expand All @@ -43,10 +42,12 @@
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
Expand All @@ -60,18 +61,60 @@
PwmConstants.URL_PREFIX_PUBLIC + "/resources/*"
}
)
public class ResourceFileServlet extends AbstractPwmServlet {
public class ResourceFileServlet extends HttpServlet implements PwmServlet {
private static final PwmLogger LOGGER = PwmLogger.forClass(ResourceFileServlet.class);


@Override
protected ProcessAction readProcessAction(PwmRequest request) throws PwmUnrecoverableException {
return null;
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
PwmRequest pwmRequest = null;
try {
pwmRequest = PwmRequest.forRequest(req, resp);
} catch (PwmUnrecoverableException e) {
LOGGER.error("unable to satisfy request using standard mechanism, reverting to raw resource server");
}

if (pwmRequest != null) {
try {
processAction(pwmRequest);
} catch (PwmUnrecoverableException e) {
LOGGER.error(pwmRequest,"error during resource servlet request processing: " + e.getMessage());
}
} else {
try {
rawRequestProcessor(req,resp);
} catch (PwmUnrecoverableException e) {
LOGGER.error("error serving raw resource request: " + e.getMessage());
}
}
}

@Override
protected void rawRequestProcessor(final HttpServletRequest req, final HttpServletResponse resp)
throws IOException, PwmUnrecoverableException
{

final FileResource file = resolveRequestedFile(
req.getServletContext(),
req.getRequestURI(),
req,
Collections.<String, ZipFile>emptyMap(),
Collections.<String, FileResource>emptyMap()
);

if (file == null || !file.exists()) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}

handleUncachedResponse(resp, file, false);
}



protected void processAction(PwmRequest pwmRequest)
throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
throws ServletException, IOException, PwmUnrecoverableException
{
if (pwmRequest.getMethod() != HttpMethod.GET) {
throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE,"unable to process resource request for request method " + pwmRequest.getMethod()));
Expand Down
Loading

0 comments on commit 41d74e3

Please sign in to comment.