Add support for metric export using prometheus bearer token

Bug: Issue 10214
Change-Id: Ia25fcbd4bc692af1da050fd9a117128bd48178c0
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java
index 632b168..a43a779 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java
@@ -14,25 +14,40 @@
 package com.googlesource.gerrit.plugins.metricsreporters;
 
 import com.codahale.metrics.MetricRegistry;
+import com.google.common.base.Strings;
+import com.google.common.net.HttpHeaders;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import io.prometheus.client.CollectorRegistry;
 import io.prometheus.client.dropwizard.DropwizardExports;
 import io.prometheus.client.exporter.MetricsServlet;
 import java.io.IOException;
+import java.util.Optional;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 @SuppressWarnings("serial")
 @Singleton
 public class GerritPrometheusExporter extends MetricsServlet {
+  private static final String PROMETHEUS_BEARER_TOKEN = "prometheusBearerToken";
+
   private final CapabilityChecker capabilityChecker;
+  private final String prometheusBearerToken;
 
   @Inject
-  public GerritPrometheusExporter(MetricRegistry registry, CapabilityChecker capabilityChecker) {
+  public GerritPrometheusExporter(
+      MetricRegistry registry,
+      CapabilityChecker capabilityChecker,
+      PluginConfigFactory cfgFactory,
+      @PluginName String pluginName) {
     this.capabilityChecker = capabilityChecker;
+    this.prometheusBearerToken =
+        cfgFactory.getFromGerritConfig(pluginName).getString(PROMETHEUS_BEARER_TOKEN);
 
     // Hook the Dropwizard registry into the Prometheus registry
     // via the DropwizardExports collector.
@@ -42,7 +57,7 @@
   @Override
   public void service(ServletRequest req, ServletResponse res)
       throws ServletException, IOException {
-    if (capabilityChecker.canViewMetrics()) {
+    if (capabilityChecker.canViewMetrics() || canExportUsingPrometheusBearerToken(req)) {
       super.service(req, res);
     } else {
       HttpServletResponse httpResponse = (HttpServletResponse) res;
@@ -50,5 +65,14 @@
     }
   }
 
-  
+  private boolean canExportUsingPrometheusBearerToken(ServletRequest req) {
+    if (Strings.isNullOrEmpty(prometheusBearerToken)) {
+      return false;
+    }
+
+    HttpServletRequest httpRequest = (HttpServletRequest) req;
+    return Optional.ofNullable(httpRequest.getHeader(HttpHeaders.AUTHORIZATION))
+        .map(h -> h.equals("Bearer " + prometheusBearerToken))
+        .orElse(false);
+  }
 }
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 0092de0..96f347e 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -4,4 +4,5 @@
 
 To access the monitoring URL, a user must be a member of a group that is granted
 the ‘View Metrics’ capability (provided by this plugin) or the ‘Administrate
-Server’ capability.
\ No newline at end of file
+Server’ capability. Alternatively, authentication using prometheus bearer token
+is also supported.
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index fa180cf..c8edf5c 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -1,9 +1,13 @@
 Configuration
 =============
 
+The configuration of the @PLUGIN@ plugin is done in the `gerrit.config`
+file.
+
 To access the monitoring URL, a user must be a member of a group that is granted
 the ‘View Metrics’ capability (provided by this plugin) or the ‘Administrate
-Server’ capability.This plugin requires no configuration.
+Server’ capability. Alternatively, authentication using prometheus bearer token
+is also supported.
 
 This capability can be configured in the 'Global Capabilities' section of the
 ['All-Projects'](@URL@#/admin/projects/All-Projects,access) access right.
@@ -11,6 +15,15 @@
 It is possible to allow anonymous access to the metrics by giving the capability
 to the 'Anonymous Users' group.
 
+plugin.@PLUGIN@.prometheusBearerToken
+:	Bearer token for allowing Prometheus to query Gerrit metrics through its scraper.
+	Defaults to undefine.
+
+When defined, access to the plugins/@PLUGIN@/metrics URL does not require any
+authentication and do not check any ACL related to the ‘View Metrics’ global capability.
+See [Prometheus documentation](https://prometheus.io/docs/prometheus/latest/configuration/configuration)
+for how to configure the integration with Prometheus.
+
 [Back to @PLUGIN@ documentation index][index]
 
-[index]: index.html
\ No newline at end of file
+[index]: index.html