Browse Source

add setting -> admin -> allow skip forced activies

jrivard@gmail.com 6 years ago
parent
commit
91a9bb8eeb

+ 1 - 0
server/src/main/java/password/pwm/bean/LoginInfoBean.java

@@ -55,6 +55,7 @@ public class LoginInfoBean implements Serializable
     {
     {
         skipOtp,
         skipOtp,
         skipNewPw,
         skipNewPw,
+        skipSetupCr,
 
 
         // bypass sso
         // bypass sso
         noSso,
         noSso,

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

@@ -1152,6 +1152,8 @@ public enum PwmSetting
     // administration
     // administration
     QUERY_MATCH_PWM_ADMIN(
     QUERY_MATCH_PWM_ADMIN(
             "pwmAdmin.queryMatch", PwmSettingSyntax.USER_PERMISSION, PwmSettingCategory.ADMINISTRATION ),
             "pwmAdmin.queryMatch", PwmSettingSyntax.USER_PERMISSION, PwmSettingCategory.ADMINISTRATION ),
+    ADMIN_ALLOW_SKIP_FORCED_ACTIVITIES(
+            "pwmAdmin.allowSkipForcedActivities", PwmSettingSyntax.BOOLEAN, PwmSettingCategory.ADMINISTRATION ),
 
 
 
 
     ENABLE_EXTERNAL_WEBSERVICES(
     ENABLE_EXTERNAL_WEBSERVICES(

+ 4 - 1
server/src/main/java/password/pwm/http/PwmRequestAttribute.java

@@ -49,8 +49,11 @@ public enum PwmRequestAttribute
     AccountInfo,
     AccountInfo,
 
 
     SetupResponses_ResponseInfo,
     SetupResponses_ResponseInfo,
+    SetupResponses_AllowSkip,
 
 
     SetupOtp_QrCodeValue,
     SetupOtp_QrCodeValue,
+    SetupOtp_AllowSkip,
+    SetupOtp_UserRecord,
 
 
     HelpdeskDetail,
     HelpdeskDetail,
     HelpdeskObfuscatedDN,
     HelpdeskObfuscatedDN,
@@ -99,5 +102,5 @@ public enum PwmRequestAttribute
 
 
     TokenDestItems,
     TokenDestItems,
 
 
-    GoBackAction,
+    GoBackAction,;
 }
 }

+ 3 - 124
server/src/main/java/password/pwm/http/bean/SetupResponsesBean.java

@@ -24,6 +24,7 @@ package password.pwm.http.bean;
 
 
 import com.novell.ldapchai.cr.Challenge;
 import com.novell.ldapchai.cr.Challenge;
 import com.novell.ldapchai.cr.ChallengeSet;
 import com.novell.ldapchai.cr.ChallengeSet;
+import lombok.Data;
 import password.pwm.config.option.SessionBeanMode;
 import password.pwm.config.option.SessionBeanMode;
 
 
 import java.io.Serializable;
 import java.io.Serializable;
@@ -32,6 +33,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
 
 
+@Data
 public class SetupResponsesBean extends PwmSessionBean
 public class SetupResponsesBean extends PwmSessionBean
 {
 {
     private boolean hasExistingResponses;
     private boolean hasExistingResponses;
@@ -47,76 +49,7 @@ public class SetupResponsesBean extends PwmSessionBean
         return Type.AUTHENTICATED;
         return Type.AUTHENTICATED;
     }
     }
 
 
-    public SetupData getResponseData( )
-    {
-        return responseData;
-    }
-
-    public void setResponseData( final SetupData responseData )
-    {
-        this.responseData = responseData;
-    }
-
-    public SetupData getHelpdeskResponseData( )
-    {
-        return helpdeskResponseData;
-    }
-
-    public void setHelpdeskResponseData( final SetupData helpdeskResponseData )
-    {
-        this.helpdeskResponseData = helpdeskResponseData;
-    }
-
-    public boolean isResponsesSatisfied( )
-    {
-        return responsesSatisfied;
-    }
-
-    public void setResponsesSatisfied( final boolean responsesSatisfied )
-    {
-        this.responsesSatisfied = responsesSatisfied;
-    }
-
-    public boolean isHelpdeskResponsesSatisfied( )
-    {
-        return helpdeskResponsesSatisfied;
-    }
-
-    public void setHelpdeskResponsesSatisfied( final boolean helpdeskResponsesSatisfied )
-    {
-        this.helpdeskResponsesSatisfied = helpdeskResponsesSatisfied;
-    }
-
-    public boolean isConfirmed( )
-    {
-        return confirmed;
-    }
-
-    public void setConfirmed( final boolean confirmed )
-    {
-        this.confirmed = confirmed;
-    }
-
-    public Locale getUserLocale( )
-    {
-        return userLocale;
-    }
-
-    public void setUserLocale( final Locale userLocale )
-    {
-        this.userLocale = userLocale;
-    }
-
-    public boolean isHasExistingResponses( )
-    {
-        return hasExistingResponses;
-    }
-
-    public void setHasExistingResponses( final boolean hasExistingResponses )
-    {
-        this.hasExistingResponses = hasExistingResponses;
-    }
-
+    @Data
     public static class SetupData implements Serializable
     public static class SetupData implements Serializable
     {
     {
         private ChallengeSet challengeSet;
         private ChallengeSet challengeSet;
@@ -124,60 +57,6 @@ public class SetupResponsesBean extends PwmSessionBean
         private boolean simpleMode;
         private boolean simpleMode;
         private int minRandomSetup;
         private int minRandomSetup;
         private Map<Challenge, String> responseMap = Collections.emptyMap();
         private Map<Challenge, String> responseMap = Collections.emptyMap();
-
-        public SetupData( )
-        {
-        }
-
-        public ChallengeSet getChallengeSet( )
-        {
-            return challengeSet;
-        }
-
-        public void setChallengeSet( final ChallengeSet challengeSet )
-        {
-            this.challengeSet = challengeSet;
-        }
-
-        public Map<String, Challenge> getIndexedChallenges( )
-        {
-            return indexedChallenges;
-        }
-
-        public void setIndexedChallenges( final Map<String, Challenge> indexedChallenges )
-        {
-            this.indexedChallenges = indexedChallenges;
-        }
-
-        public boolean isSimpleMode( )
-        {
-            return simpleMode;
-        }
-
-        public void setSimpleMode( final boolean simpleMode )
-        {
-            this.simpleMode = simpleMode;
-        }
-
-        public int getMinRandomSetup( )
-        {
-            return minRandomSetup;
-        }
-
-        public void setMinRandomSetup( final int minRandomSetup )
-        {
-            this.minRandomSetup = minRandomSetup;
-        }
-
-        public Map<Challenge, String> getResponseMap( )
-        {
-            return responseMap;
-        }
-
-        public void setResponseMap( final Map<Challenge, String> responseMap )
-        {
-            this.responseMap = responseMap;
-        }
     }
     }
 
 
     @Override
     @Override

+ 1 - 1
server/src/main/java/password/pwm/http/filter/AuthenticationFilter.java

@@ -452,7 +452,7 @@ public class AuthenticationFilter extends AbstractPwmFilter
         }
         }
 
 
 
 
-        if ( userInfo.isRequiresResponseConfig() )
+        if ( userInfo.isRequiresResponseConfig() && !pwmSession.getLoginInfoBean().isLoginFlag( LoginInfoBean.LoginFlag.skipSetupCr ) )
         {
         {
             if ( !pwmURL.isSetupResponsesURL() )
             if ( !pwmURL.isSetupResponsesURL() )
             {
             {

+ 35 - 15
server/src/main/java/password/pwm/http/servlet/SetupOtpServlet.java

@@ -25,6 +25,7 @@ package password.pwm.http.servlet;
 import com.novell.ldapchai.exception.ChaiUnavailableException;
 import com.novell.ldapchai.exception.ChaiUnavailableException;
 import net.glxn.qrgen.QRCode;
 import net.glxn.qrgen.QRCode;
 import password.pwm.AppProperty;
 import password.pwm.AppProperty;
+import password.pwm.Permission;
 import password.pwm.PwmApplication;
 import password.pwm.PwmApplication;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.bean.LoginInfoBean;
 import password.pwm.bean.LoginInfoBean;
@@ -232,7 +233,10 @@ public class SetupOtpServlet extends ControlledPwmServlet
         }
         }
         else
         else
         {
         {
+            final boolean allowSkip = checkIfAllowedToSkipSetup( pwmRequest );
             final String qrCodeValue = makeQrCodeDataImageUrl( pwmRequest, otpBean.getOtpUserRecord() );
             final String qrCodeValue = makeQrCodeDataImageUrl( pwmRequest, otpBean.getOtpUserRecord() );
+            pwmRequest.setAttribute(  PwmRequestAttribute.SetupOtp_UserRecord, otpBean.getOtpUserRecord() );
+            pwmRequest.setAttribute( PwmRequestAttribute.SetupOtp_AllowSkip, allowSkip );
             pwmRequest.setAttribute( PwmRequestAttribute.SetupOtp_QrCodeValue, qrCodeValue );
             pwmRequest.setAttribute( PwmRequestAttribute.SetupOtp_QrCodeValue, qrCodeValue );
             pwmRequest.forwardToJsp( JspUrl.SETUP_OTP_SECRET );
             pwmRequest.forwardToJsp( JspUrl.SETUP_OTP_SECRET );
         }
         }
@@ -245,21 +249,7 @@ public class SetupOtpServlet extends ControlledPwmServlet
     )
     )
             throws PwmUnrecoverableException, IOException, ServletException, ChaiUnavailableException
             throws PwmUnrecoverableException, IOException, ServletException, ChaiUnavailableException
     {
     {
-
-        boolean allowSkip = false;
-        if ( !pwmRequest.isForcedPageView() )
-        {
-            allowSkip = true;
-        }
-        else
-        {
-            final SetupOtpProfile setupOtpProfile = getSetupOtpProfile( pwmRequest );
-            final ForceSetupPolicy policy = setupOtpProfile.readSettingAsEnum( PwmSetting.OTP_FORCE_SETUP, ForceSetupPolicy.class );
-            if ( policy == ForceSetupPolicy.FORCE_ALLOW_SKIP )
-            {
-                allowSkip = true;
-            }
-        }
+        final boolean allowSkip = checkIfAllowedToSkipSetup( pwmRequest );
 
 
         if ( allowSkip )
         if ( allowSkip )
         {
         {
@@ -526,4 +516,34 @@ public class SetupOtpServlet extends ControlledPwmServlet
 
 
         return "data:image/png;base64," + StringUtil.base64Encode( imageBytes );
         return "data:image/png;base64," + StringUtil.base64Encode( imageBytes );
     }
     }
+
+    private static boolean checkIfAllowedToSkipSetup( final PwmRequest pwmRequest )
+            throws PwmUnrecoverableException
+    {
+        if ( pwmRequest.isForcedPageView() )
+        {
+            final SetupOtpProfile setupOtpProfile = getSetupOtpProfile( pwmRequest );
+            final ForceSetupPolicy policy = setupOtpProfile.readSettingAsEnum( PwmSetting.OTP_FORCE_SETUP, ForceSetupPolicy.class );
+
+            if ( policy == ForceSetupPolicy.FORCE_ALLOW_SKIP )
+            {
+                LOGGER.trace( pwmRequest, "allowing setup skipping due to setting "
+                        + PwmSetting.OTP_FORCE_SETUP.toMenuLocationDebug( setupOtpProfile.getIdentifier(), pwmRequest.getLocale() ) );
+                return true;
+            }
+
+            final boolean admin = pwmRequest.getPwmSession().getSessionManager().checkPermission( pwmRequest.getPwmApplication(), Permission.PWMADMIN );
+            if ( admin )
+            {
+                if ( pwmRequest.getConfig().readSettingAsBoolean( PwmSetting.ADMIN_ALLOW_SKIP_FORCED_ACTIVITIES ) )
+                {
+                    LOGGER.trace( pwmRequest, "allowing OTP setup skipping due to user being admin and setting "
+                            + PwmSetting.ADMIN_ALLOW_SKIP_FORCED_ACTIVITIES.toMenuLocationDebug( null, pwmRequest.getLocale() ) );
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
 }
 }

+ 45 - 1
server/src/main/java/password/pwm/http/servlet/SetupResponsesServlet.java

@@ -35,6 +35,7 @@ import lombok.Value;
 import password.pwm.Permission;
 import password.pwm.Permission;
 import password.pwm.PwmApplication;
 import password.pwm.PwmApplication;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
+import password.pwm.bean.LoginInfoBean;
 import password.pwm.bean.ResponseInfoBean;
 import password.pwm.bean.ResponseInfoBean;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.profile.ChallengeProfile;
 import password.pwm.config.profile.ChallengeProfile;
@@ -97,7 +98,8 @@ public class SetupResponsesServlet extends ControlledPwmServlet
         setHelpdeskResponses( HttpMethod.POST ),
         setHelpdeskResponses( HttpMethod.POST ),
         confirmResponses( HttpMethod.POST ),
         confirmResponses( HttpMethod.POST ),
         clearExisting( HttpMethod.POST ),
         clearExisting( HttpMethod.POST ),
-        changeResponses( HttpMethod.POST ),;
+        changeResponses( HttpMethod.POST ),
+        skip ( HttpMethod.POST ),;
 
 
         private final HttpMethod method;
         private final HttpMethod method;
 
 
@@ -228,6 +230,26 @@ public class SetupResponsesServlet extends ControlledPwmServlet
         return ProcessStatus.Continue;
         return ProcessStatus.Continue;
     }
     }
 
 
+    @ActionHandler( action = "skip" )
+    private ProcessStatus handleSkip(
+            final PwmRequest pwmRequest
+    )
+            throws PwmUnrecoverableException, ChaiUnavailableException, IOException
+    {
+        LOGGER.trace( pwmRequest, "request for skip received" );
+
+        final boolean allowSkip = checkIfAllowSkipCr( pwmRequest );
+
+        if ( allowSkip )
+        {
+            pwmRequest.getPwmSession().getLoginInfoBean().getLoginFlags().add( LoginInfoBean.LoginFlag.skipSetupCr );
+            pwmRequest.sendRedirectToContinue();
+            return ProcessStatus.Halt;
+        }
+
+        return ProcessStatus.Continue;
+    }
+
     @ActionHandler( action = "validateResponses" )
     @ActionHandler( action = "validateResponses" )
     private ProcessStatus restValidateResponses(
     private ProcessStatus restValidateResponses(
             final PwmRequest pwmRequest
             final PwmRequest pwmRequest
@@ -305,6 +327,8 @@ public class SetupResponsesServlet extends ControlledPwmServlet
 
 
         if ( !setupResponsesBean.isResponsesSatisfied() )
         if ( !setupResponsesBean.isResponsesSatisfied() )
         {
         {
+            final boolean allowskip = checkIfAllowSkipCr( pwmRequest );
+            pwmRequest.setAttribute( PwmRequestAttribute.SetupResponses_AllowSkip, allowskip );
             pwmRequest.forwardToJsp( JspUrl.SETUP_RESPONSES );
             pwmRequest.forwardToJsp( JspUrl.SETUP_RESPONSES );
             return;
             return;
         }
         }
@@ -684,5 +708,25 @@ public class SetupResponsesServlet extends ControlledPwmServlet
         private String message;
         private String message;
         private boolean success;
         private boolean success;
     }
     }
+
+    private static boolean checkIfAllowSkipCr( final PwmRequest pwmRequest )
+            throws PwmUnrecoverableException
+    {
+        if ( pwmRequest.isForcedPageView() )
+        {
+            final boolean admin = pwmRequest.getPwmSession().getSessionManager().checkPermission( pwmRequest.getPwmApplication(), Permission.PWMADMIN );
+            if ( admin )
+            {
+                if ( pwmRequest.getConfig().readSettingAsBoolean( PwmSetting.ADMIN_ALLOW_SKIP_FORCED_ACTIVITIES ) )
+                {
+                    LOGGER.trace( pwmRequest, "allowing c/r answer setup skipping due to user being admin and setting "
+                            + PwmSetting.ADMIN_ALLOW_SKIP_FORCED_ACTIVITIES.toMenuLocationDebug( null, pwmRequest.getLocale() ) );
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
 }
 }
 
 

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

@@ -519,6 +519,11 @@
             <value/>
             <value/>
         </default>
         </default>
     </setting>
     </setting>
+    <setting hidden="false" key="pwmAdmin.allowSkipForcedActivities" level="0" required="true">
+        <default>
+            <value>true</value>
+        </default>
+    </setting>
     <setting hidden="false" key="ldap.usernameSearchFilter" level="1" required="true">
     <setting hidden="false" key="ldap.usernameSearchFilter" level="1" required="true">
         <default>
         <default>
             <value><![CDATA[(&(objectClass=person)(cn=%USERNAME%))]]></value>
             <value><![CDATA[(&(objectClass=person)(cn=%USERNAME%))]]></value>

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

@@ -596,6 +596,7 @@ Setting_Description_peopleSearch.searchBase=Specify the LDAP search bases for th
 Setting_Description_peopleSearch.searchFilter=Specify the LDAP search filter the People Search module uses to query the directory.  Substitute <i>%USERNAME%</i> for user-supplied user names. If blank, @PwmAppName@ auto-generates the search filter based on the values in the setting <a data-gotoSettingLink\="peopleSearch.searchAttributes">@PwmSettingReference\:peopleSearch.searchAttributes@</a>.\n        <br/><br>\n        Example\: <code>(&(objectClass\=Person)(|(givenName\=*%USERNAME%*)(sn\=*%USERNAME%*)(mail\=*%USERNAME%*)(telephoneNumber\=*%USERNAME%*)))</code>\n\n
 Setting_Description_peopleSearch.searchFilter=Specify the LDAP search filter the People Search module uses to query the directory.  Substitute <i>%USERNAME%</i> for user-supplied user names. If blank, @PwmAppName@ auto-generates the search filter based on the values in the setting <a data-gotoSettingLink\="peopleSearch.searchAttributes">@PwmSettingReference\:peopleSearch.searchAttributes@</a>.\n        <br/><br>\n        Example\: <code>(&(objectClass\=Person)(|(givenName\=*%USERNAME%*)(sn\=*%USERNAME%*)(mail\=*%USERNAME%*)(telephoneNumber\=*%USERNAME%*)))</code>\n\n
 Setting_Description_peopleSearch.useProxy=Enable this option to use the LDAP proxy account to perform searches. For proper security in most environments, do <b>not</b> enable this setting.
 Setting_Description_peopleSearch.useProxy=Enable this option to use the LDAP proxy account to perform searches. For proper security in most environments, do <b>not</b> enable this setting.
 Setting_Description_pwmAdmin.queryMatch=Specify the permissions @PwmAppName@ uses to determine if it grants a user administrator rights.
 Setting_Description_pwmAdmin.queryMatch=Specify the permissions @PwmAppName@ uses to determine if it grants a user administrator rights.
+Setting_Description_pwmAdmin.allowSkipForcedActivities=Allow administrators to skip otherwised forced activities such as setup of challenge/response answers. 
 Setting_Description_pwm.appProperty.overrides=(Troubleshooting only) Specify an override application properties value.  Do not use unless directed to by a support expert.
 Setting_Description_pwm.appProperty.overrides=(Troubleshooting only) Specify an override application properties value.  Do not use unless directed to by a support expert.
 Setting_Description_pwm.forwardURL=Specify a URL that @PwmAppName@ forwards users to after the users complete any activity which does not require a log out.<br/><br/>You can override this setting for any given user session by adding a <i>forwardURL</i> parameter to any HTTP request. If blank, the system forwards the user to the @PwmAppName@ menu.
 Setting_Description_pwm.forwardURL=Specify a URL that @PwmAppName@ forwards users to after the users complete any activity which does not require a log out.<br/><br/>You can override this setting for any given user session by adding a <i>forwardURL</i> parameter to any HTTP request. If blank, the system forwards the user to the @PwmAppName@ menu.
 Setting_Description_pwm.homeURL=Specify the URL to redirect the user to upon clicking the home button. If blank, the home button returns the user to the application context URL.
 Setting_Description_pwm.homeURL=Specify the URL to redirect the user to upon clicking the home button. If blank, the home button returns the user to the application context URL.
@@ -1097,6 +1098,7 @@ Setting_Label_peopleSearch.searchBase=LDAP Search base
 Setting_Label_peopleSearch.searchFilter=People Search LDAP Filter
 Setting_Label_peopleSearch.searchFilter=People Search LDAP Filter
 Setting_Label_peopleSearch.useProxy=Use Proxy Account
 Setting_Label_peopleSearch.useProxy=Use Proxy Account
 Setting_Label_pwmAdmin.queryMatch=Administrator Permission
 Setting_Label_pwmAdmin.queryMatch=Administrator Permission
+Setting_Label_pwmAdmin.allowSkipForcedActivities=Allow Admin to Skip Forced Activities
 Setting_Label_pwm.appProperty.overrides=App Property Overrides
 Setting_Label_pwm.appProperty.overrides=App Property Overrides
 Setting_Label_pwm.forwardURL=Forward URL
 Setting_Label_pwm.forwardURL=Forward URL
 Setting_Label_pwm.homeURL=Home URL
 Setting_Label_pwm.homeURL=Home URL

+ 2 - 23
webapp/src/main/webapp/WEB-INF/jsp/setupotpsecret.jsp

@@ -20,33 +20,15 @@
  ~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  ~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 --%>
 --%>
 
 
-<%@page import="password.pwm.config.option.ForceSetupPolicy"%>
-<%@page import="password.pwm.http.bean.SetupOtpBean"%>
 <%@ page import="password.pwm.http.tag.conditional.PwmIfTest" %>
 <%@ page import="password.pwm.http.tag.conditional.PwmIfTest" %>
 <%@ page import="password.pwm.util.operations.otp.OTPUserRecord" %>
 <%@ page import="password.pwm.util.operations.otp.OTPUserRecord" %>
 <%@ page import="password.pwm.http.PwmRequestAttribute" %>
 <%@ page import="password.pwm.http.PwmRequestAttribute" %>
-<%@ page import="password.pwm.config.profile.SetupOtpProfile" %>
-<%@ page import="password.pwm.http.servlet.SetupOtpServlet" %>
 <!DOCTYPE html>
 <!DOCTYPE html>
 <%@ page language="java" session="true" isThreadSafe="true"
 <%@ page language="java" session="true" isThreadSafe="true"
          contentType="text/html" %>
          contentType="text/html" %>
 <%@ taglib uri="pwm" prefix="pwm" %>
 <%@ taglib uri="pwm" prefix="pwm" %>
-<%
-    OTPUserRecord otpUserRecord = null;
-    boolean allowSkip = false;
-    boolean forcedPageView = false;
-    try {
-        final PwmRequest pwmRequest = JspUtility.getPwmRequest( pageContext );
-        final SetupOtpBean setupOtpBean = JspUtility.getSessionBean(pageContext, SetupOtpBean.class);
-        final SetupOtpProfile setupOtpProfile = SetupOtpServlet.getSetupOtpProfile( pwmRequest );
-        otpUserRecord = setupOtpBean.getOtpUserRecord();
-        allowSkip = setupOtpProfile.readSettingAsEnum(PwmSetting.OTP_FORCE_SETUP, ForceSetupPolicy.class) == ForceSetupPolicy.FORCE_ALLOW_SKIP;
-        forcedPageView = pwmRequest.isForcedPageView();
-    } catch (PwmUnrecoverableException e) {
-        /* application must be unavailable */
-    }
-
-%>
+<% OTPUserRecord otpUserRecord = (OTPUserRecord) JspUtility.getAttribute( pageContext, PwmRequestAttribute.SetupOtp_UserRecord ); %>
+<% boolean allowSkip = JspUtility.getBooleanAttribute( pageContext, PwmRequestAttribute.SetupOtp_AllowSkip ); %>
 <html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
 <html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
 <%@ include file="fragment/header.jsp" %>
 <%@ include file="fragment/header.jsp" %>
 <body class="nihilo">
 <body class="nihilo">
@@ -107,14 +89,12 @@
             <form action="<pwm:current-url/>" method="post" name="setupOtpSecret-skip" enctype="application/x-www-form-urlencoded" id="setupOtpSecret-skip" class="pwm-form">
             <form action="<pwm:current-url/>" method="post" name="setupOtpSecret-skip" enctype="application/x-www-form-urlencoded" id="setupOtpSecret-skip" class="pwm-form">
                 <input type="hidden" name="processAction" value="skip"/>
                 <input type="hidden" name="processAction" value="skip"/>
                 <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
                 <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
-                <% if (forcedPageView) { %>
                 <% if (allowSkip) { %>
                 <% if (allowSkip) { %>
                 <button type="submit" name="continue" class="btn" id="skipbutton">
                 <button type="submit" name="continue" class="btn" id="skipbutton">
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-fighter-jet"></span></pwm:if>
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-fighter-jet"></span></pwm:if>
                     <pwm:display key="Button_Skip"/>
                     <pwm:display key="Button_Skip"/>
                 </button>
                 </button>
                 <% } %>
                 <% } %>
-                <% } else { %>
                 <pwm:if test="<%=PwmIfTest.showCancel%>">
                 <pwm:if test="<%=PwmIfTest.showCancel%>">
                     <pwm:if test="<%=PwmIfTest.forcedPageView%>" negate="true">
                     <pwm:if test="<%=PwmIfTest.forcedPageView%>" negate="true">
                         <button type="submit" name="button" class="btn" id="button-cancel">
                         <button type="submit" name="button" class="btn" id="button-cancel">
@@ -123,7 +103,6 @@
                         </button>
                         </button>
                     </pwm:if>
                     </pwm:if>
                 </pwm:if>
                 </pwm:if>
-                <% } %>
             </form>
             </form>
         </div>
         </div>
     </div>
     </div>

+ 11 - 0
webapp/src/main/webapp/WEB-INF/jsp/setupresponses.jsp

@@ -26,6 +26,7 @@
 <%@ page language="java" session="true" isThreadSafe="true" contentType="text/html" %>
 <%@ page language="java" session="true" isThreadSafe="true" contentType="text/html" %>
 <%@ taglib uri="pwm" prefix="pwm" %>
 <%@ taglib uri="pwm" prefix="pwm" %>
 <% final SetupResponsesBean responseBean = (SetupResponsesBean)JspUtility.getAttribute(pageContext, PwmRequestAttribute.ModuleBean); %>
 <% final SetupResponsesBean responseBean = (SetupResponsesBean)JspUtility.getAttribute(pageContext, PwmRequestAttribute.ModuleBean); %>
+<% final boolean allowSkip = JspUtility.getBooleanAttribute( pageContext, PwmRequestAttribute.SetupResponses_AllowSkip ); %>
 <html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
 <html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
 <%@ include file="fragment/header.jsp" %>
 <%@ include file="fragment/header.jsp" %>
 <body class="nihilo">
 <body class="nihilo">
@@ -50,11 +51,21 @@
                 </button>
                 </button>
                 <%@ include file="/WEB-INF/jsp/fragment/cancel-button.jsp" %>
                 <%@ include file="/WEB-INF/jsp/fragment/cancel-button.jsp" %>
                 <input type="hidden" id="pwmFormID" name="pwmFormID" value="<pwm:FormID/>"/>
                 <input type="hidden" id="pwmFormID" name="pwmFormID" value="<pwm:FormID/>"/>
+                <% if (allowSkip) { %>
+                <button type="submit" name="skip" class="btn" id="skipbutton" form="skipForm">
+                    <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-fighter-jet"></span></pwm:if>
+                    <pwm:display key="Button_Skip"/>
+                </button>
+                <% } %>
             </div>
             </div>
         </form>
         </form>
     </div>
     </div>
     <div class="push"></div>
     <div class="push"></div>
 </div>
 </div>
+<form class="hidden" action="<pwm:current-url/>" method="post" name="skipForm" id="skipForm" enctype="application/x-www-form-urlencoded" class="pwmForm">
+    <input type="hidden" name="<%=PwmConstants.PARAM_ACTION_REQUEST%>" value="skip"/>
+    <input type="hidden" name="<%=PwmConstants.PARAM_FORM_ID%>" value="<pwm:FormID/>"/>
+</form>
 <pwm:script>
 <pwm:script>
     <script type="text/javascript">
     <script type="text/javascript">
         PWM_GLOBAL['responseMode'] = "user";
         PWM_GLOBAL['responseMode'] = "user";