Merge branch 'stable-2.16' into master

* stable-2.16:
  Respect auth.userNameToLowerCase configuration

Change-Id: I454683f72f52fbc2235ff2c1f79dca457047332a
diff --git a/README.md b/README.md
index bb9c949..0425eaf 100644
--- a/README.md
+++ b/README.md
@@ -179,7 +179,14 @@
 
 Default is `UserName`
 
-**saml.serviceProviderEntityId**: Saml service provider entity id
+**saml.serviceProviderEntityId**: SAML service provider entity id.
+
+Default is not set.
+
+**saml.identityProviderEntityId**: SAML identity provider entity id.  When present
+a `IDPSSODescriptor` is expected in the SAML metadata document.  When absent a
+saml service provider with its `SPSSODescriptor` is assumed.
+This value takes precedence over the value in **saml.serviceProviderEntityId**.
 
 Default is not set.
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlConfig.java b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlConfig.java
index d5aae19..98f09ea 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlConfig.java
@@ -23,7 +23,7 @@
 @Singleton
 public class SamlConfig {
   private static final String SAML_SECTION = "saml";
-
+  private final String identityProviderEntityId;
   private final String serviceProviderEntityId;
   private final String metadataPath;
   private final String keystorePath;
@@ -42,6 +42,7 @@
   @Inject
   SamlConfig(@GerritServerConfig Config cfg) {
     serviceProviderEntityId = getString(cfg, "serviceProviderEntityId");
+    identityProviderEntityId = getString(cfg, "identityProviderEntityId");
     metadataPath = getString(cfg, "metadataPath");
     keystorePath = getString(cfg, "keystorePath");
     privateKeyPassword = getString(cfg, "privateKeyPassword");
@@ -119,4 +120,8 @@
   public boolean useNameQualifier() {
     return useNameQualifier;
   }
+
+  public String getIdentityProviderEntityId() {
+    return identityProviderEntityId;
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
index dddb17a..b91f539 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
@@ -81,14 +81,23 @@
         new SAML2Configuration(
             samlConfig.getKeystorePath(), samlConfig.getKeystorePassword(),
             samlConfig.getPrivateKeyPassword(), samlConfig.getMetadataPath());
-    samlClientConfig.setMaximumAuthenticationLifetime(samlConfig.getMaxAuthLifetimeAttr());
-    samlClientConfig.setServiceProviderMetadataPath(
-        ensureExists(sitePaths.data_dir).resolve("sp-metadata.xml").toString());
-    if (!Strings.isNullOrEmpty(samlConfig.getServiceProviderEntityId())) {
-      samlClientConfig.setServiceProviderEntityId(samlConfig.getServiceProviderEntityId());
+
+    if (!Strings.isNullOrEmpty(samlConfig.getIdentityProviderEntityId())) {
+      if (!Strings.isNullOrEmpty(samlConfig.getServiceProviderEntityId())) {
+        log.warn(
+            "Both identityProviderEntityId as serviceProviderEntityId are set, ignoring serviceProviderEntityId.");
+      }
+      samlClientConfig.setIdentityProviderEntityId(samlConfig.getIdentityProviderEntityId());
+    } else {
+      samlClientConfig.setServiceProviderMetadataPath(
+          ensureExists(sitePaths.data_dir).resolve("sp-metadata.xml").toString());
+      if (!Strings.isNullOrEmpty(samlConfig.getServiceProviderEntityId())) {
+        samlClientConfig.setServiceProviderEntityId(samlConfig.getServiceProviderEntityId());
+      }
     }
 
     samlClientConfig.setUseNameQualifier(samlConfig.useNameQualifier());
+    samlClientConfig.setMaximumAuthenticationLifetime(samlConfig.getMaxAuthLifetimeAttr());
 
     saml2Client = new SAML2Client(samlClientConfig);
     String callbackUrl = gerritConfig.getString("gerrit", null, "canonicalWebUrl") + SAML_CALLBACK;