Using MicrosoftAzureActiveDirectory20Api from scribejava-apis

* Using MicrosoftAzureActiveDirectory20Api from scribejava-apis, this is
  intended to be used with Microsoft Azure oauth v2.

* If Google OAuth plugin is set to use a tenant other than common,
  organizations or consumers the token will be validated that they are
  originating from the same tenant that is configured in the Gerrit
  OAuth plugin.

Change-Id: Id293be463281fc8fa34af5edf61e774b207dcc21
diff --git a/BUILD b/BUILD
index b5d591b..0d2e0e4 100644
--- a/BUILD
+++ b/BUILD
@@ -22,6 +22,7 @@
     deps = [
         "@commons-codec//jar:neverlink",
         "@jackson-databind//jar",
+        "@scribejava-apis//jar",
         "@scribejava-core//jar",
     ],
 )
@@ -32,6 +33,7 @@
     tags = ["oauth"],
     deps = [
         ":oauth__plugin_test_deps",
+        "@scribejava-apis//jar",
         "@scribejava-core//jar",
     ],
 )
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 4615c8d..ffe8a31 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -2,12 +2,18 @@
 
 def external_plugin_deps(omit_commons_codec = True):
     JACKSON_VERS = "2.10.2"
+    SCRIBEJAVA_VERS = "6.9.0"
     maven_jar(
         name = "scribejava-core",
-        artifact = "com.github.scribejava:scribejava-core:6.9.0",
+        artifact = "com.github.scribejava:scribejava-core:" + SCRIBEJAVA_VERS,
         sha1 = "ed761f450d8382f75787e8fee9ae52e7ec768747",
     )
     maven_jar(
+        name = "scribejava-apis",
+        artifact = "com.github.scribejava:scribejava-apis:" + SCRIBEJAVA_VERS,
+        sha1 = "a374c7a36533e58e53b42b584a8b3751ab1e13c4",
+    )
+    maven_jar(
         name = "jackson-annotations",
         artifact = "com.fasterxml.jackson.core:jackson-annotations:" + JACKSON_VERS,
         sha1 = "3a13b6105946541b8d4181a0506355b5fae63260",
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java
deleted file mode 100644
index 4a3d0e1..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.googlesource.gerrit.plugins.oauth;
-
-import com.github.scribejava.core.builder.api.DefaultApi20;
-import com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication;
-import com.github.scribejava.core.oauth2.clientauthentication.RequestBodyAuthenticationScheme;
-
-public class Office365Api extends DefaultApi20 {
-  public static final String DEFAULT_TENANT = "organizations";
-
-  private final String tenant;
-
-  public Office365Api() {
-    this(DEFAULT_TENANT);
-  }
-
-  public Office365Api(String tenant) {
-    this.tenant = tenant;
-  }
-
-  @Override
-  public String getAccessTokenEndpoint() {
-    return endpointFor("token");
-  }
-
-  @Override
-  public String getAuthorizationBaseUrl() {
-    return endpointFor("authorize");
-  }
-
-  private String endpointFor(String suffix) {
-    return String.format("https://login.microsoftonline.com/%s/oauth2/v2.0/%s", tenant, suffix);
-  }
-
-  @Override
-  public ClientAuthentication getClientAuthentication() {
-    return RequestBodyAuthenticationScheme.instance();
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java
index 3df8937..bdafd92 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java
@@ -16,6 +16,7 @@
 
 import static com.google.gerrit.json.OutputFormat.JSON;
 
+import com.github.scribejava.apis.MicrosoftAzureActiveDirectory20Api;
 import com.github.scribejava.core.builder.ServiceBuilder;
 import com.github.scribejava.core.exceptions.OAuthException;
 import com.github.scribejava.core.model.OAuth2AccessToken;
@@ -24,6 +25,7 @@
 import com.github.scribejava.core.model.Verb;
 import com.github.scribejava.core.oauth.OAuth20Service;
 import com.google.common.base.CharMatcher;
+import com.google.common.collect.ImmutableSet;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider;
 import com.google.gerrit.extensions.auth.oauth.OAuthToken;
@@ -54,6 +56,9 @@
   private static final String PROTECTED_RESOURCE_URL = "https://graph.microsoft.com/v1.0/me";
   private static final String SCOPE =
       "openid offline_access https://graph.microsoft.com/user.readbasic.all";
+  private static final String DEFAULT_TENANT = "organizations";
+  private static final ImmutableSet<String> TENANTS_WITHOUT_VALIDATION =
+      ImmutableSet.<String>builder().add(DEFAULT_TENANT).add("common").add("consumers").build();
   private final OAuth20Service service;
   private final Gson gson;
   private final String canonicalWebUrl;
@@ -69,14 +74,14 @@
     PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX);
     this.canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/";
     this.useEmailAsUsername = cfg.getBoolean(InitOAuth.USE_EMAIL_AS_USERNAME, false);
-    this.tenant = cfg.getString(InitOAuth.TENANT, Office365Api.DEFAULT_TENANT);
+    this.tenant = cfg.getString(InitOAuth.TENANT, DEFAULT_TENANT);
     this.clientId = cfg.getString(InitOAuth.CLIENT_ID);
     this.service =
         new ServiceBuilder(cfg.getString(InitOAuth.CLIENT_ID))
             .apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET))
             .callback(canonicalWebUrl + "oauth")
             .defaultScope(SCOPE)
-            .build(new Office365Api(tenant));
+            .build(MicrosoftAzureActiveDirectory20Api.custom(tenant));
     this.gson = JSON.newGson();
     if (log.isDebugEnabled()) {
       log.debug("OAuth2: canonicalWebUrl={}", canonicalWebUrl);
@@ -87,11 +92,10 @@
 
   @Override
   public OAuthUserInfo getUserInfo(OAuthToken token) throws IOException {
-    // ?: Have we set a custom tenant, if so we should validate that the token is issued by the same
-    // tenant as
-    // we have set.
-    if (!tenant.equals(Office365Api.DEFAULT_TENANT)) {
-      // -> Yes, we are using a non-default tenant so we should validate that is delegated from the
+    // ?: Have we set a custom tenant and is this a tenant other than the one set in
+    // TENANTS_WITHOUT_VALIDATION
+    if (!TENANTS_WITHOUT_VALIDATION.contains(tenant)) {
+      // -> Yes, we are using a tenant that should be validated, so verify that is issued for the
       // same one that we
       // have set.
       String tid = getTokenJson(token.getToken()).get("tid").getAsString();
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 98b0b56..fec6ecb 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -241,14 +241,13 @@
 ```
 
 ####Tenant
-By default, the Gerrit OAuth plugin is using the tenant `organizations`. A specific tenant can be set
-by using the option `tenant`.
+The Gerrit OAuth plugin is default set to use the tenant `organizations` but a specific tenant can be used by 
+the option `tenant`. If a tenant other than `common`, `organizations` or `consumers` is used then the tokens will be
+validated that they are originating from the same tenant that is configured in the Gerrit OAuth plugin.
+See [https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc#fetch-the-openid-connect-metadata-document](Microsoft identity platform and OpenID Connect protocol)
 ```
 plugin.gerrit-oauth-provider-office365-oauth.tenant = <tenant to use>
 ```
 
-If a specific tenant is set Gerrit OAuth plugin will inspect the token and validate that this is
-originating from the Azure AD with the tenant specified in the option.
-
-By default, all tokens will be checked that they contain the client_id set
+Regardless of tenant all tokens will be checked that they contain the client_id set
 in the Gerrit OAuth plugin.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java b/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java
index 6bcf313..a725167 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java
@@ -16,16 +16,17 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.github.scribejava.apis.MicrosoftAzureActiveDirectory20Api;
 import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor;
 import org.junit.Before;
 import org.junit.Test;
 
 public class Office365ApiTest {
-  private Office365Api api;
+  private MicrosoftAzureActiveDirectory20Api api;
 
   @Before
   public void setUp() {
-    api = new Office365Api();
+    api = MicrosoftAzureActiveDirectory20Api.instance();
   }
 
   @Test