浏览代码

setup responses controlledservlet refactoring

Jason Rivard 8 年之前
父节点
当前提交
8afcadfa52

+ 0 - 2
src/main/java/password/pwm/config/PwmSetting.java

@@ -513,8 +513,6 @@ public enum PwmSetting {
             "enableSessionVerification", PwmSettingSyntax.SELECT, PwmSettingCategory.WEB_SECURITY),
     DISALLOWED_HTTP_INPUTS(
             "disallowedInputs", PwmSettingSyntax.STRING_ARRAY, PwmSettingCategory.WEB_SECURITY),
-    REQUIRE_HTTPS(
-            "pwm.requireHTTPS", PwmSettingSyntax.BOOLEAN, PwmSettingCategory.WEB_SECURITY),
     USE_X_FORWARDED_FOR_HEADER(
             "useXForwardedForHeader", PwmSettingSyntax.BOOLEAN, PwmSettingCategory.WEB_SECURITY),
     MULTI_IP_SESSION_ALLOWED(

+ 0 - 6
src/main/java/password/pwm/http/filter/SessionFilter.java

@@ -167,12 +167,6 @@ public class SessionFilter extends AbstractPwmFilter {
         //check the sso override flag
         handleSsoOverrideParam(pwmRequest);
 
-        // make sure connection is secure.
-        if (config.readSettingAsBoolean(PwmSetting.REQUIRE_HTTPS) && !pwmRequest.getHttpServletRequest().isSecure()) {
-            pwmRequest.respondWithError(PwmError.ERROR_SECURE_REQUEST_REQUIRED.toInfo());
-            return ProcessStatus.Halt;
-        }
-
         //check for session verification failure
         if (!ssBean.isSessionVerified()) {
             // ignore resource requests

+ 100 - 105
src/main/java/password/pwm/http/servlet/SetupResponsesServlet.java

@@ -45,6 +45,7 @@ import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.http.HttpMethod;
 import password.pwm.http.JspUrl;
+import password.pwm.http.ProcessStatus;
 import password.pwm.http.PwmRequest;
 import password.pwm.http.PwmSession;
 import password.pwm.http.bean.SetupResponsesBean;
@@ -55,8 +56,6 @@ import password.pwm.svc.event.AuditEvent;
 import password.pwm.svc.event.AuditRecordFactory;
 import password.pwm.svc.event.UserAuditRecord;
 import password.pwm.svc.stats.Statistic;
-import password.pwm.util.Validator;
-import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.logging.PwmLogger;
@@ -85,7 +84,7 @@ import java.util.Map;
                 PwmConstants.URL_PREFIX_PRIVATE + "/SetupResponses",
         }
 )
-public class SetupResponsesServlet extends AbstractPwmServlet {
+public class SetupResponsesServlet extends ControlledPwmServlet {
 
     private static final PwmLogger LOGGER = PwmLogger.forClass(SetupResponsesServlet.class);
 
@@ -122,13 +121,15 @@ public class SetupResponsesServlet extends AbstractPwmServlet {
         }
     }
 
-    protected void processAction(final PwmRequest pwmRequest)
-            throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
-    {
-        // fetch the required beans / managers
+    private SetupResponsesBean getSetupResponseBean(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
+        return pwmRequest.getPwmApplication().getSessionStateService().getBean(pwmRequest, SetupResponsesBean.class);
+    }
+
+    @Override
+    public void preProcessCheck(final PwmRequest pwmRequest) throws PwmUnrecoverableException, IOException, ServletException {
         final PwmSession pwmSession = pwmRequest.getPwmSession();
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
-        final UserInfoBean uiBean = pwmSession.getUserInfoBean();
+        final SetupResponsesBean setupResponsesBean = getSetupResponseBean(pwmRequest);
 
         if (!pwmSession.isAuthenticated()) {
             pwmRequest.respondWithError(PwmError.ERROR_AUTHENTICATION_REQUIRED.toInfo());
@@ -140,14 +141,12 @@ public class SetupResponsesServlet extends AbstractPwmServlet {
         }
 
         if (!pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.CHALLENGE_ENABLE)) {
-            pwmRequest.respondWithError(PwmError.ERROR_SERVICE_NOT_AVAILABLE.toInfo());
-            return;
+            throw new PwmUnrecoverableException(PwmError.ERROR_SERVICE_NOT_AVAILABLE);
         }
 
         // check to see if the user is permitted to setup responses
         if (!pwmSession.getSessionManager().checkPermission(pwmApplication, Permission.SETUP_RESPONSE)) {
-            pwmRequest.respondWithError(PwmError.ERROR_UNAUTHORIZED.toInfo());
-            return;
+            throw new PwmUnrecoverableException(PwmError.ERROR_UNAUTHORIZED);
         }
 
         // check if the locale has changed since first seen.
@@ -156,63 +155,41 @@ public class SetupResponsesServlet extends AbstractPwmServlet {
             pwmApplication.getSessionStateService().getBean(pwmRequest, SetupResponsesBean.class).setUserLocale(pwmSession.getSessionStateBean().getLocale());
         }
 
-        SetupResponsesBean setupResponsesBean = pwmApplication.getSessionStateService().getBean(pwmRequest, SetupResponsesBean.class);
         initializeBean(pwmRequest, setupResponsesBean);
 
         // check to see if the user has any challenges assigned
+        final UserInfoBean uiBean = pwmSession.getUserInfoBean();
         if (setupResponsesBean.getResponseData().getChallengeSet() == null || setupResponsesBean.getResponseData().getChallengeSet().getChallenges().isEmpty()) {
-            LOGGER.debug(pwmSession, "no challenge sets configured for user " + uiBean.getUserIdentity());
-            pwmRequest.respondWithError(PwmError.ERROR_NO_CHALLENGES.toInfo());
-            return;
+            final String errorMsg = "no challenge sets configured for user " + uiBean.getUserIdentity();
+            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NO_CHALLENGES, errorMsg);
+            LOGGER.debug(pwmSession, errorInformation);
+            throw new PwmUnrecoverableException(errorInformation);
         }
+    }
 
-        // read the action request parameter
-        final SetupResponsesAction action = readProcessAction(pwmRequest);
-
-        if (action != null) {
-            Validator.validatePwmFormID(pwmRequest);
-
-            switch (action) {
-                case validateResponses:
-                    restValidateResponses(pwmRequest, setupResponsesBean);
-                    return;
-
-                case setResponses:
-                    handleSetupResponses(pwmRequest, setupResponsesBean, false);
-                    break;
-
-                case setHelpdeskResponses:
-                    handleSetupResponses(pwmRequest, setupResponsesBean, true);
-                    break;
-
-                case confirmResponses:
-                    setupResponsesBean.setConfirmed(true);
-                    break;
-
-                case clearExisting:
-                    handleClearResponses(pwmRequest);
-                    return;
-
-                case changeResponses:
-                    pwmApplication.getSessionStateService().clearBean(pwmRequest, SetupResponsesBean.class);
-                    setupResponsesBean = pwmApplication.getSessionStateService().getBean(pwmRequest, SetupResponsesBean.class);
-                    this.initializeBean(pwmRequest, setupResponsesBean);
-                    setupResponsesBean.setUserLocale(pwmSession.getSessionStateBean().getLocale());
-                    break;
-
-                default:
-                    JavaHelper.unhandledSwitchStatement(action);
-
-            }
-        }
+    @ActionHandler(action = "confirmResponses")
+    private ProcessStatus processConfirmResponses(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
+        final SetupResponsesBean setupResponsesBean = getSetupResponseBean(pwmRequest);
+        setupResponsesBean.setConfirmed(true);
+        return ProcessStatus.Continue;
+    }
 
-        this.advanceToNextStage(pwmRequest, setupResponsesBean);
+    @ActionHandler(action = "changeResponses")
+    private ProcessStatus processChangeResponses(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
+        final SetupResponsesBean setupResponsesBean = getSetupResponseBean(pwmRequest);
+        final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
+        pwmApplication.getSessionStateService().clearBean(pwmRequest, SetupResponsesBean.class);
+        this.initializeBean(pwmRequest, setupResponsesBean);
+        setupResponsesBean.setUserLocale(pwmRequest.getLocale());
+        return ProcessStatus.Continue;
     }
 
-    private void handleClearResponses(
+    @ActionHandler(action = "clearExisting")
+    private ProcessStatus handleClearResponses(
             final PwmRequest pwmRequest
     )
-            throws PwmUnrecoverableException, ChaiUnavailableException, IOException {
+            throws PwmUnrecoverableException, ChaiUnavailableException, IOException
+    {
         LOGGER.trace(pwmRequest, "request for response clear received");
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmSession pwmSession = pwmRequest.getPwmSession();
@@ -235,16 +212,73 @@ public class SetupResponsesServlet extends AbstractPwmServlet {
             pwmRequest.sendRedirect(PwmServletDefinition.SetupResponses);
         } catch (PwmOperationalException e) {
             LOGGER.debug(pwmSession, e.getErrorInformation());
-            pwmRequest.setResponseError(e.getErrorInformation());
+            setLastError(pwmRequest, e.getErrorInformation());
         }
+        return ProcessStatus.Continue;
     }
 
-    private void advanceToNextStage(
-            final PwmRequest pwmRequest,
-            final SetupResponsesBean setupResponsesBean
+    @ActionHandler(action = "validateResponses")
+    private ProcessStatus restValidateResponses(
+            final PwmRequest pwmRequest
     )
-            throws PwmUnrecoverableException, IOException, ServletException, ChaiUnavailableException
+            throws IOException, ServletException, PwmUnrecoverableException, ChaiUnavailableException
     {
+        final SetupResponsesBean setupResponsesBean = getSetupResponseBean(pwmRequest);
+        final Instant startTime = Instant.now();
+        final PwmSession pwmSession = pwmRequest.getPwmSession();
+        final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
+        final String responseModeParam = pwmRequest.readParameterAsString("responseMode");
+        final SetupResponsesBean.SetupData setupData = "helpdesk".equalsIgnoreCase(responseModeParam)
+                ? setupResponsesBean.getHelpdeskResponseData()
+                : setupResponsesBean.getResponseData();
+
+        boolean success = true;
+        String userMessage = Message.getLocalizedMessage(pwmSession.getSessionStateBean().getLocale(), Message.Success_ResponsesMeetRules, pwmApplication.getConfig());
+
+        try {
+            // read in the responses from the request
+            final Map<Challenge, String> responseMap = readResponsesFromJsonRequest(pwmRequest, setupData);
+            final int minRandomRequiredSetup = setupData.getMinRandomSetup();
+            pwmApplication.getCrService().validateResponses(setupData.getChallengeSet(), responseMap, minRandomRequiredSetup);
+            generateResponseInfoBean(pwmRequest, setupData.getChallengeSet(), responseMap, Collections.emptyMap());
+        } catch (PwmDataValidationException e) {
+            success = false;
+            userMessage = e.getErrorInformation().toUserStr(pwmSession, pwmApplication);
+        }
+
+        final ValidationResponseBean validationResponseBean = new ValidationResponseBean(userMessage,success);
+        final RestResultBean restResultBean = new RestResultBean(validationResponseBean);
+        LOGGER.trace(pwmRequest,"completed rest validate response in "
+                + TimeDuration.fromCurrent(startTime).asCompactString()
+                + ", result=" + JsonUtil.serialize(restResultBean));
+        pwmRequest.outputJsonResult(restResultBean);
+        return ProcessStatus.Halt;
+    }
+
+    @ActionHandler(action = "setHelpdeskResponses")
+    private ProcessStatus processSetHelpdeskResponses(final PwmRequest pwmRequest)
+            throws ChaiUnavailableException, PwmUnrecoverableException, ServletException, IOException
+    {
+        setupResponses(pwmRequest, true);
+        return ProcessStatus.Continue;
+    }
+
+    @ActionHandler(action = "setResponses")
+    private ProcessStatus processSetResponses(final PwmRequest pwmRequest)
+            throws ChaiUnavailableException, PwmUnrecoverableException, ServletException, IOException
+    {
+        setupResponses(pwmRequest, false);
+        return ProcessStatus.Continue;
+    }
+
+    @Override
+    protected void nextStep(final PwmRequest pwmRequest)
+            throws PwmUnrecoverableException, IOException, ChaiUnavailableException, ServletException
+    {
+        final SetupResponsesBean setupResponsesBean = getSetupResponseBean(pwmRequest);
+
+        initializeBean(pwmRequest, setupResponsesBean);
+
         pwmRequest.setAttribute(PwmRequest.Attribute.ModuleBean, setupResponsesBean);
         pwmRequest.setAttribute(PwmRequest.Attribute.ModuleBean_String, pwmRequest.getPwmApplication().getSecureService().encryptObjectToString(setupResponsesBean));
         pwmRequest.setAttribute(PwmRequest.Attribute.SetupResponses_ResponseInfo, pwmRequest.getPwmSession().getUserInfoBean().getResponseInfoBean());
@@ -297,52 +331,14 @@ public class SetupResponsesServlet extends AbstractPwmServlet {
         }
     }
 
-    /**
-     * Handle requests for ajax feedback of user supplied responses.
-     */
-    private static void restValidateResponses(
-            final PwmRequest pwmRequest,
-            final SetupResponsesBean setupResponsesBean
-    )
-            throws IOException, ServletException, PwmUnrecoverableException, ChaiUnavailableException
-    {
-        final Instant startTime = Instant.now();
-        final PwmSession pwmSession = pwmRequest.getPwmSession();
-        final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
-        final String responseModeParam = pwmRequest.readParameterAsString("responseMode");
-        final SetupResponsesBean.SetupData setupData = "helpdesk".equalsIgnoreCase(responseModeParam)
-                ? setupResponsesBean.getHelpdeskResponseData()
-                : setupResponsesBean.getResponseData();
 
-        boolean success = true;
-        String userMessage = Message.getLocalizedMessage(pwmSession.getSessionStateBean().getLocale(), Message.Success_ResponsesMeetRules, pwmApplication.getConfig());
-
-        try {
-            // read in the responses from the request
-            final Map<Challenge, String> responseMap = readResponsesFromJsonRequest(pwmRequest, setupData);
-            final int minRandomRequiredSetup = setupData.getMinRandomSetup();
-            pwmApplication.getCrService().validateResponses(setupData.getChallengeSet(), responseMap, minRandomRequiredSetup);
-            generateResponseInfoBean(pwmRequest, setupData.getChallengeSet(), responseMap, Collections.emptyMap());
-        } catch (PwmDataValidationException e) {
-            success = false;
-            userMessage = e.getErrorInformation().toUserStr(pwmSession, pwmApplication);
-        }
-
-        final ValidationResponseBean validationResponseBean = new ValidationResponseBean(userMessage,success);
-        final RestResultBean restResultBean = new RestResultBean(validationResponseBean);
-        LOGGER.trace(pwmRequest,"completed rest validate response in "
-                + TimeDuration.fromCurrent(startTime).asCompactString()
-                + ", result=" + JsonUtil.serialize(restResultBean));
-        pwmRequest.outputJsonResult(restResultBean);
-    }
-
-    private void handleSetupResponses(
+    private void setupResponses(
             final PwmRequest pwmRequest,
-            final SetupResponsesBean setupResponsesBean,
             final boolean helpdeskMode
     )
             throws PwmUnrecoverableException, IOException, ServletException, ChaiUnavailableException
     {
+        final SetupResponsesBean setupResponsesBean = getSetupResponseBean(pwmRequest);
         final SetupResponsesBean.SetupData setupData = helpdeskMode ? setupResponsesBean.getHelpdeskResponseData() : setupResponsesBean.getResponseData();
 
         final ChallengeSet challengeSet = setupData.getChallengeSet();
@@ -356,7 +352,7 @@ public class SetupResponsesServlet extends AbstractPwmServlet {
             pwmRequest.getPwmApplication().getCrService().validateResponses(challengeSet, responseMap, minRandomRequiredSetup);
         } catch (PwmDataValidationException e) {
             LOGGER.debug(pwmRequest, "error with new " + (helpdeskMode ? "helpdesk" : "user") + " responses: " + e.getErrorInformation().toDebugStr());
-            pwmRequest.setResponseError(e.getErrorInformation());
+            setLastError(pwmRequest, e.getErrorInformation());
             return;
         }
 
@@ -539,7 +535,6 @@ public class SetupResponsesServlet extends AbstractPwmServlet {
     {
         if (pwmRequest.getPwmSession().getUserInfoBean().getResponseInfoBean() != null) {
             setupResponsesBean.setHasExistingResponses(true);
-
         }
 
         final ChallengeProfile challengeProfile = pwmRequest.getPwmSession().getUserInfoBean().getChallengeProfile();

+ 1 - 0
src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordServlet.java

@@ -362,6 +362,7 @@ public class ForgottenPasswordServlet extends ControlledPwmServlet {
 
         if (forgottenPasswordBean.getUserIdentity() == null) {
             pwmRequest.sendRedirectToContinue();
+            return ProcessStatus.Halt;
         }
 
         return ProcessStatus.Continue;

+ 5 - 1
src/main/java/password/pwm/util/Helper.java

@@ -102,7 +102,11 @@ public class Helper {
 
 
     public static String buildPwmFormID(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
-        final SessionStateService sessionStateService = pwmRequest.getPwmApplication().getSessionStateService();
+        final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
+        if (pwmApplication == null) {
+            return "";
+        }
+        final SessionStateService sessionStateService = pwmApplication.getSessionStateService();
         final String value = sessionStateService.getSessionStateInfo(pwmRequest);
         final FormNonce formID = new FormNonce(
                 pwmRequest.getPwmSession().getLoginInfoBean().getGuid(),

+ 0 - 5
src/main/resources/password/pwm/config/PwmSetting.xml

@@ -1415,11 +1415,6 @@
             <value><![CDATA[(?s)(?i)<.*href.*]]></value>
         </default>
     </setting>
-    <setting hidden="false" key="pwm.requireHTTPS" level="1" required="true">
-        <default>
-            <value>false</value>
-        </default>
-    </setting>
     <setting hidden="false" key="basicAuth.enable" level="2" required="true">
         <default>
             <value>true</value>

+ 0 - 2
src/main/resources/password/pwm/i18n/PwmSetting.properties

@@ -579,7 +579,6 @@ Setting_Description_pwmInstanceName=Specify the name of this application instanc
 Setting_Description_pwm.logoutURL=Specify the URL to redirect user to upon logout. If users access the site through a web authentication gateway, set the Logout URL to the gateway's Logout URL. If you are using a gateway and do not include the proper logout URL here, then users encounter authentication errors, intruder lockouts, and other problems. If things are working properly then the users see the gateway log out screen when logging out.<br/><br/>You can set the Logout URL to any appropriate relative or absolute URL.  At the time the user's browser requests this URL, the local session has already been invalidated.<br/><br/>You can always override this setting for any given user session by adding a <b>logoutURL</b> parameter to any HTTP request during the session.
 Setting_Description_pwm.publishStats.enable=Enable this option to periodically publish the statistics of this application to the project website. The published statistics are\:<ul><li>Instance Name</li><li>Version/Build Information</li><li>Cumulative Statistics</li><li>Which settings are non-default (but not the actual setting values)</li></ul>Leaving this feature enabled helps developers know which features the administrators use.
 Setting_Description_pwm.publishStats.siteDescription=Specify this optional site description if you enabled Anonymous statistics publishing. @PwmAppName@ publishes this site description along with the otherwise anonymous statistics.  This can be an organization name or other similar value.
-Setting_Description_pwm.requireHTTPS=Enable this option to require HTTPS (instead of cleartext HTTP) traffic to the @PwmAppName@ server.  While non-secure connections are useful during testing, production servers must always have this setting enabled.
 Setting_Description_pwm.securityKey=<p>Specify a Security Key used for cryptographic functions such as the token verification. @PwmAppName@ requires a value if you enabled tokens for any of modules and configured a token storage method. @PwmAppName@ uses this value similar to how a cryptographic security certificate uses the private key.</p> <p>If configured, this value must be at least 32 characters in length.  The longer and more random this value, the more secure its uses are.  If multiple instances are in use, you must configure each instance with the same value.</p><p>Upon initial setup, @PwmAppName@ assigns a random security key to this value that you can change at any time, however, any outstanding tokens or other material generated by an old security key become invalid.</p>
 Setting_Description_pwm.seedlist.location=Specify the location of the seed list in the form of a valid URL. When @PwmAppName@ randomly generates passwords, it can generate a "friendly", random password suggestions to users.  It does this by using a "seed" word or words, and then modifying that word randomly until it is sufficiently complex and meets the configured rules computed for the user.<br/><br/>The value must be a valid URL, using the protocol "file" (local file system), "http", or "https".
 Setting_Description_pwm.selfURL=<p>The URL to this application, as seen by users. @PwmAppName@ uses the value in email macros and other user-facing communications.</p><p>The URL must use a valid fully qualified hostname. Do not use a network address.</p><p>In simple environments, the URL will be the base of the URL in the browser you are currently using to view this page, however in more complex environments the URL will typically be an upstream proxy, gateway or network device.</p>
@@ -1054,7 +1053,6 @@ Setting_Label_pwmInstanceName=Instance Name
 Setting_Label_pwm.logoutURL=Logout URL
 Setting_Label_pwm.publishStats.enable=Enable Anonymous Statistics Publishing
 Setting_Label_pwm.publishStats.siteDescription=Site Description
-Setting_Label_pwm.requireHTTPS=Require HTTPS
 Setting_Label_pwm.securityKey=Security Key
 Setting_Label_pwm.seedlist.location=Seed List File URL
 Setting_Label_pwm.selfURL=Site URL