Office365 OAuth: Add support for specifying a tenant

* Added new InitOauth parameter 'tenant'.

* If the parameter 'tenant' is not set it will default to the tenant
  'organizations'.

* If the parameter 'tenant' is set it will use a specific AD to
  authenticate the users.

Change-Id: Id4c9e659b238dda2ad417901ddf6462f82324da0
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java
index 854ba5b..6f7ca01 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java
@@ -34,6 +34,7 @@
   static final String USE_EMAIL_AS_USERNAME = "use-email-as-username";
   static final String ROOT_URL = "root-url";
   static final String REALM = "realm";
+  static final String TENANT = "tenant";
   static final String SERVICE_NAME = "service-name";
   static String FIX_LEGACY_USER_ID_QUESTION = "Fix legacy user id, without oauth provider prefix?";
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java
index 7e9bef8..4a3d0e1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java
@@ -19,14 +19,30 @@
 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 "https://login.microsoftonline.com/organizations/oauth2/v2.0/token";
+    return endpointFor("token");
   }
 
   @Override
   public String getAuthorizationBaseUrl() {
-    return "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize";
+    return endpointFor("authorize");
+  }
+
+  private String endpointFor(String suffix) {
+    return String.format("https://login.microsoftonline.com/%s/oauth2/v2.0/%s", tenant, suffix);
   }
 
   @Override
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 4e0803b..1edec0e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java
@@ -53,6 +53,7 @@
   private final OAuth20Service service;
   private final String canonicalWebUrl;
   private final boolean useEmailAsUsername;
+  private final String tenant;
 
   @Inject
   Office365OAuthService(
@@ -62,12 +63,13 @@
     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.service =
         new ServiceBuilder(cfg.getString(InitOAuth.CLIENT_ID))
             .apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET))
             .callback(canonicalWebUrl + "oauth")
             .defaultScope(SCOPE)
-            .build(new Office365Api());
+            .build(new Office365Api(tenant));
     if (log.isDebugEnabled()) {
       log.debug("OAuth2: canonicalWebUrl={}", canonicalWebUrl);
       log.debug("OAuth2: scope={}", SCOPE);
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 19eb426..24addfd 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -48,6 +48,11 @@
     client-id = "<client-id>"
     client-secret = "<client-secret>"
     root-url = "<phabricator url>"
+
+  [plugin "@PLUGIN@-office365-oauth"]
+    client-id = "<client-id>"
+    client-secret = "<client-secret>"
+    tenant = "<tenant (optional defaults to organizations if not set)>"
 ```
 
 When one from the sections above is omitted, OAuth SSO is used.
@@ -222,3 +227,22 @@
 The client-id and client-secret for Phabricator can be obtained by registering a
 Client application.
 See [Using the Phabricator OAuth Server](https://secure.phabricator.com/book/phabcontrib/article/using_oauthserver/).
+
+### Office365
+The client-id and client-secret for Office365/Azure can be obtained by registering a new application,
+see [OAuth 2.0 and OpenID Connect protocols on Microsoft identity platform](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols).
+
+####Username
+By default Office365 OAuth will not set a username (used for ssh) and the user can choose one from the web ui
+(needed before using ssh). To automatically set the user part from the email the option *use-email-as-username*
+can be used.
+```
+plugin.gerrit-oauth-provider-office365-oauth.use-email-as-username = true
+```
+
+####Tenant
+By default, the Gerrit OAuth plugin is using the tenant `organizations`. A specific tenant can be set
+by using the option `tenant`.
+```
+plugin.gerrit-oauth-provider-office365-oauth.tenant = <tenant to use>
+```