[SYNCOPE-1811] MFA bypass properties (#665)

diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.java
index eec6a0b..76833d3 100644
--- a/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.java
+++ b/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.java
@@ -28,6 +28,7 @@
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
 import org.apache.syncope.common.lib.policy.AuthPolicyTO;
 import org.apache.syncope.common.lib.to.AuthModuleTO;
@@ -79,6 +80,24 @@
                 "authModules",
                 new PropertyModel<>(model.getObject().getConf(), "authModules"),
                 allAuthModules));
+
+        add(new AjaxCheckBoxPanel(
+                "bypassEnabled",
+                "bypassEnabled",
+                new PropertyModel<>(model.getObject().getConf(), "bypassEnabled"),
+                false));
+
+        add(new AjaxTextFieldPanel(
+                "bypassPrincipalAttributeName",
+                "bypassPrincipalAttributeName",
+                new PropertyModel<>(model.getObject().getConf(), "bypassPrincipalAttributeName"),
+                false));
+
+        add(new AjaxTextFieldPanel(
+                "bypassPrincipalAttributeValue",
+                "bypassPrincipalAttributeValue",
+                new PropertyModel<>(model.getObject().getConf(), "bypassPrincipalAttributeValue"),
+                false));
     }
 
     @Override
diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.html b/client/am/console/src/main/resources/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.html
index b71bbf3..e66a972 100644
--- a/client/am/console/src/main/resources/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.html
+++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.html
@@ -24,5 +24,14 @@
     <div class="form-group">
       <span wicket:id="authModules"/>
     </div>
+    <div class="form-group">
+      <span wicket:id="bypassEnabled"/>
+    </div>
+    <div class="form-group">
+      <span wicket:id="bypassPrincipalAttributeName"/>
+    </div>
+    <div class="form-group">
+      <span wicket:id="bypassPrincipalAttributeValue"/>
+    </div>
   </wicket:extend>
 </html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.properties
index 0f90076..d5451c6 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.properties
@@ -55,3 +55,6 @@
 enable.proxyTgtConf=Enable Proxy TGT
 enable.proxyStConf=Enable Proxy ST
 auditHistory.title=Configuration history
+bypassEnabled=Enable Bypass
+bypassPrincipalAttributeName=Bypass Principal Attribute Name
+bypassPrincipalAttributeValue=Bypass Principal Attribute Value
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_fr_CA.properties
index 840dcbc..a951aa0 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_fr_CA.properties
@@ -55,3 +55,6 @@
 enable.proxyTgtConf=Enable Proxy TGT
 enable.proxyStConf=Enable Proxy ST
 auditHistory.title=Historique de configuration
+bypassEnabled=Enable Bypass
+bypassPrincipalAttributeName=Bypass Principal Attribute Name
+bypassPrincipalAttributeValue=Bypass Principal Attribute Value
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_it.properties
index c612240..a55a004 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_it.properties
@@ -55,3 +55,6 @@
 enable.proxyTgtConf=Abilita Proxy TGT
 enable.proxyStConf=Abilita Proxy ST
 auditHistory.title=Storico delle configurazioni
+bypassEnabled=Abilita Bypass
+bypassPrincipalAttributeName=Bypass Nome Attributo
+bypassPrincipalAttributeValue=Bypass Valore Attributo
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ja.properties
index 4499e1b..bd417f8 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ja.properties
@@ -55,3 +55,7 @@
 enable.proxyTgtConf=Enable Proxy TGT
 enable.proxyStConf=Enable Proxy ST
 auditHistory.title=\u8a2d\u5b9a\u5c65\u6b74
+bypassEnabled=Enable Bypass
+bypassPrincipalAttributeName=Bypass Principal Attribute Name
+bypassPrincipalAttributeValue=Bypass Principal Attribute Value
+
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_pt_BR.properties
index 4799d48..f189b1a 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_pt_BR.properties
@@ -55,3 +55,6 @@
 enable.proxyTgtConf=Enable Proxy TGT
 enable.proxyStConf=Enable Proxy ST
 auditHistory.title=Hist\u00f3rico de configura\u00e7\u00e3o
+bypassEnabled=Enable Bypass
+bypassPrincipalAttributeName=Bypass Principal Attribute Name
+bypassPrincipalAttributeValue=Bypass Principal Attribute Value
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ru.properties
index 9148686..e767cb8 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ru.properties
@@ -56,3 +56,6 @@
 enable.proxyTgtConf=Enable Proxy TGT
 enable.proxyStConf=Enable Proxy ST
 auditHistory.title=\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438
+bypassEnabled=Enable Bypass
+bypassPrincipalAttributeName=Bypass Principal Attribute Name
+bypassPrincipalAttributeValue=Bypass Principal Attribute Value
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAuthPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAuthPolicyConf.java
index d78ef7c..b0a4b4f 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAuthPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAuthPolicyConf.java
@@ -29,6 +29,12 @@
 
     private boolean tryAll;
 
+    private boolean bypassEnabled;
+
+    private String bypassPrincipalAttributeName;
+
+    private String bypassPrincipalAttributeValue;
+
     private final List<String> authModules = new ArrayList<>();
 
     public boolean isTryAll() {
@@ -39,6 +45,30 @@
         this.tryAll = tryAll;
     }
 
+    public boolean isBypassEnabled() {
+        return bypassEnabled;
+    }
+
+    public void setBypassEnabled(final boolean bypassEnabled) {
+        this.bypassEnabled = bypassEnabled;
+    }
+
+    public String getBypassPrincipalAttributeName() {
+        return bypassPrincipalAttributeName;
+    }
+
+    public void setBypassPrincipalAttributeName(final String bypassPrincipalAttributeName) {
+        this.bypassPrincipalAttributeName = bypassPrincipalAttributeName;
+    }
+
+    public String getBypassPrincipalAttributeValue() {
+        return bypassPrincipalAttributeValue;
+    }
+
+    public void setBypassPrincipalAttributeValue(final String bypassPrincipalAttributeValue) {
+        this.bypassPrincipalAttributeValue = bypassPrincipalAttributeValue;
+    }
+
     @JacksonXmlElementWrapper(localName = "authModules")
     @JacksonXmlProperty(localName = "authModule")
     public List<String> getAuthModules() {
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAuthMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAuthMapper.java
index 14549dc..68fca8a 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAuthMapper.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAuthMapper.java
@@ -23,6 +23,7 @@
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.auth.MFAAuthModuleConf;
 import org.apache.syncope.common.lib.auth.Pac4jAuthModuleConf;
@@ -78,8 +79,9 @@
             delegatedAuthHandlers.addAll(authModules.stream().
                     filter(m -> m.getConf() instanceof Pac4jAuthModuleConf).
                     map(m -> Pair.of(
-                    m.getKey(),
-                    Optional.ofNullable(((Pac4jAuthModuleConf) m.getConf()).getClientName()).orElse(m.getKey()))).
+                            m.getKey(),
+                            Optional.ofNullable(((Pac4jAuthModuleConf) m.getConf()).getClientName())
+                                    .orElse(m.getKey()))).
                     collect(Collectors.toSet()));
             if (!delegatedAuthHandlers.isEmpty()) {
                 authHandlers.removeAll(delegatedAuthHandlers.stream().map(Pair::getLeft).collect(Collectors.toSet()));
@@ -110,7 +112,15 @@
                     collect(Collectors.toSet());
 
             mfaPolicy = new DefaultRegisteredServiceMultifactorPolicy();
-            mfaPolicy.setBypassEnabled(false);
+
+            if (StringUtils.isNotBlank(policyConf.getBypassPrincipalAttributeName())
+                    && StringUtils.isNotBlank(policyConf.getBypassPrincipalAttributeValue())) {
+                mfaPolicy.setBypassPrincipalAttributeName(policyConf.getBypassPrincipalAttributeName());
+                mfaPolicy.setBypassPrincipalAttributeValue(policyConf.getBypassPrincipalAttributeValue());
+            } else {
+                mfaPolicy.setBypassEnabled(policyConf.isBypassEnabled());
+            }
+
             mfaPolicy.setForceExecution(true);
             mfaPolicy.setMultifactorAuthenticationProviders(mfaProviders);
         }