Add maxAuthLifetime configuration to SamlConfig

maxAuthLifetime = 86400
If no entry included in the gerrit.config the default of
86400 (24 * 60 * 60) is assumed.

This was recently added to the SAML plugin for jenkins to combat
org.pac4j.saml.exceptions.SAMLException:
   Authentication issue instant is too old or in the future
Likewise, this should help with gerrit.

Logs in error_log:
[main] INFO  com.thesamet.gerrit.plugins.saml.SamlWebFilter
    : Max Authentication Lifetime: 86400

Builds against:
 - gerrit-plugin-api version 2.13.12
 - org.pac4j.pac4j-saml version 2.0.0-RC1

Forced change from pac4j-saml update removes RequiresHttpAction
in favor of HTTPAction. Also removes boolean parameter
from saml2Client.redirect(context, true) to saml2Client.redirect(context);

PR: https://github.com/thesamet/gerrit-saml-plugin/pull/12
Change-Id: If4b8dae65a5f14608551c2a158be529cb7ced967
diff --git a/README.md b/README.md
index fd5309a..e7ea1b4 100644
--- a/README.md
+++ b/README.md
@@ -110,6 +110,10 @@
 keystore (needs to be the same as the password provided throguh the `keystore`
 flag above.)
 
+**saml.maxAuthLifetime**: (Optional) Max Authentication Lifetime (secs) configuration.
+
+Default is `86400`
+
 **saml.displayNameAttr**: Gerrit will look for an attribute with this name in
 the assertion to find a display name for the user. If the attribute is not
 found, the NameId from the SAML assertion is used instead.
diff --git a/build.sbt b/build.sbt
index f008805..5648170 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,8 +1,8 @@
 name := "gerrit-saml-plugin"
 
-val GerritVersion = "2.12.9"
+val GerritVersion = "2.13.12"
 
-version := GerritVersion + "-1"
+version := GerritVersion + "-6"
 
 scalaVersion := "2.12.8"
 
@@ -10,7 +10,7 @@
 
 libraryDependencies += ("com.google.gerrit" % "gerrit-plugin-api" % GerritVersion % "provided")
 
-libraryDependencies += "org.pac4j" % "pac4j-saml" % "1.8.0-RC1"
+libraryDependencies += "org.pac4j" % "pac4j-saml" % "2.0.0-RC1"
 
 libraryDependencies ~= { _ map {
   case m => m
@@ -36,7 +36,9 @@
 assemblyMergeStrategy in assembly := {
   case PathList("META-INF", "INDEX.LIST") => MergeStrategy.discard
   case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
+  case PathList("META-INF", "NOTICE.txt") => MergeStrategy.discard
   case PathList("META-INF", "NOTICE") => MergeStrategy.discard
+  case PathList("META-INF", "LICENSE.txt") => MergeStrategy.concat
   case PathList("META-INF", "LICENSE") => MergeStrategy.concat
   // Trick is here: get all the initializers concatenated...
   case PathList("META-INF", "services", "org.opensaml.core.config.Initializer") => MergeStrategy.concat
diff --git a/src/main/java/com/thesamet/gerrit/plugins/saml/SamlConfig.java b/src/main/java/com/thesamet/gerrit/plugins/saml/SamlConfig.java
index ffca75f..15af687 100644
--- a/src/main/java/com/thesamet/gerrit/plugins/saml/SamlConfig.java
+++ b/src/main/java/com/thesamet/gerrit/plugins/saml/SamlConfig.java
@@ -32,6 +32,8 @@
   private final String displayNameAttr;
   private final String userNameAttr;
   private final String emailAddressAttr;
+  private final String maxAuthLifetimeAttr;
+  private final int maxAuthLifetimeDefault = 24 * 60 * 60; // 24h;
 
   @Inject
   SamlConfig(@GerritServerConfig final Config cfg) {
@@ -44,6 +46,8 @@
     userNameAttr = getGetStringWithDefault(cfg, "userNameAttr", "UserName");
     emailAddressAttr =
         getGetStringWithDefault(cfg, "emailAddressAttr", "EmailAddress");
+    maxAuthLifetimeAttr =
+            getGetStringWithDefault(cfg, "maxAuthLifetime", Integer.toString(maxAuthLifetimeDefault));
   }
 
   public String getMetadataPath() {
@@ -74,6 +78,19 @@
     return emailAddressAttr;
   }
 
+  public String getMaxAuthLifetimeAttr() { return maxAuthLifetimeAttr; }
+
+  public int getMaxAuthLifetime() {
+    int maxLifetime;
+    try {
+      maxLifetime = Integer.parseInt(getMaxAuthLifetimeAttr());
+    } catch (NumberFormatException nfe) {
+      SamlWebFilter.logError("Error reading \"maxAuthLifetime\" attribute in gerrit.config. Please use digits only");
+      throw nfe;  //rethrow so the server stops launching.
+    }
+    return maxLifetime;
+  }
+
   private static String getString(Config cfg, String name) {
     return cfg.getString("saml", null, name);
   }
diff --git a/src/main/java/com/thesamet/gerrit/plugins/saml/SamlWebFilter.java b/src/main/java/com/thesamet/gerrit/plugins/saml/SamlWebFilter.java
index 9149a8b..b7e0379 100644
--- a/src/main/java/com/thesamet/gerrit/plugins/saml/SamlWebFilter.java
+++ b/src/main/java/com/thesamet/gerrit/plugins/saml/SamlWebFilter.java
@@ -22,7 +22,7 @@
 import com.google.inject.Singleton;
 import org.eclipse.jgit.lib.Config;
 import org.pac4j.core.context.J2EContext;
-import org.pac4j.core.exception.RequiresHttpAction;
+import org.pac4j.core.exception.HttpAction;
 import org.pac4j.core.exception.TechnicalException;
 import org.pac4j.saml.client.SAML2Client;
 import org.pac4j.saml.client.SAML2ClientConfiguration;
@@ -67,10 +67,13 @@
     @Inject
     SamlWebFilter(@GerritServerConfig Config gerritConfig, SamlConfig samlConfig) {
         this.samlConfig = samlConfig;
+        log.info("Max Authentication Lifetime: "+ samlConfig.getMaxAuthLifetime());
+        SAML2ClientConfiguration samlClientConfig = new SAML2ClientConfiguration(
+                samlConfig.getKeystorePath(), samlConfig.getKeystorePassword(),
+                samlConfig.getPrivateKeyPassword(), samlConfig.getMetadataPath());
+        samlClientConfig.setMaximumAuthenticationLifetime(samlConfig.getMaxAuthLifetime());
         saml2Client =
-                new SAML2Client(new SAML2ClientConfiguration(
-                        samlConfig.getKeystorePath(), samlConfig.getKeystorePassword(),
-                        samlConfig.getPrivateKeyPassword(), samlConfig.getMetadataPath()));
+                new SAML2Client(samlClientConfig);
         String callbackUrl = gerritConfig.getString("gerrit", null, "canonicalWebUrl") + "plugins/gerrit-saml-plugin/saml";
         httpUserNameHeader = getHeaderFromConfig(gerritConfig, "httpHeader");
         httpDisplaynameHeader = getHeaderFromConfig(gerritConfig, "httpDisplaynameHeader");
@@ -109,7 +112,7 @@
         else return user;
     }
 
-    private void signin(J2EContext context) throws RequiresHttpAction, IOException {
+    private void signin(J2EContext context) throws HttpAction, IOException {
         SAML2Credentials credentials = saml2Client.getCredentials(context);
         SAML2Profile user = saml2Client.getUserProfile(credentials, context);
         if (user != null) {
@@ -159,13 +162,13 @@
             } else {
                 chain.doFilter(httpRequest, httpResponse);
             }
-        } catch (final RequiresHttpAction requiresHttpAction) {
+        } catch (final HttpAction requiresHttpAction) {
             throw new TechnicalException("Unexpected HTTP action", requiresHttpAction);
         }
     }
 
     private void redirectToIdentityProvider(J2EContext context)
-            throws RequiresHttpAction {
+            throws HttpAction {
         String redirectUri = Url.decode(context
                 .getRequest()
                 .getRequestURI()
@@ -173,7 +176,7 @@
                         context.getRequest().getContextPath().length()));
         context.setSessionAttribute(SAML2Client.SAML_RELAY_STATE_ATTRIBUTE, redirectUri);
         log.debug("Setting redirectUri: {}", redirectUri);
-        saml2Client.redirect(context, true);
+        saml2Client.redirect(context);
     }
 
     private static boolean isGerritLogin(HttpServletRequest request) {
@@ -264,6 +267,14 @@
         }
     }
 
+    public static void logWarning(String message) {
+        log.warn(message);
+    }
+
+    public static void logError(String message) {
+        log.error(message);
+    }
+
     private class AnonymousHttpRequest extends HttpServletRequestWrapper {
         public AnonymousHttpRequest(HttpServletRequest request) {
             super(request);