Rename Office365AuthService to AzureActiveDirectoryService

* Running plugin init step will check for previously installed
  Office365 oauth and if it is found it will ask the user y/n
  based on the Office365 naming.
  If no configuration for Office365 where found it will ask to install
  Azure oauth instead.

* Added link-to-existing-office365-accounts to support automatic linking
  of any old Office365 accounts.

Change-Id: I52e8834f5c9bac0c62f5f9b19523341f0e94c874
diff --git a/README.md b/README.md
index de036fb..3e70431 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@
 * [Google](https://developers.google.com/identity/protocols/OAuth2)
 * [Keycloak](http://www.keycloak.org/)
 * [LemonLDAP::NG](https://lemonldap-ng.org)
-* [Office365](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols)
+* [Azure (previously named Office365)](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols)
 * [Phabricator](https://secure.phabricator.com/book/phabcontrib/article/using_oauthserver/)
 
 See the [Wiki](https://github.com/davido/gerrit-oauth-provider/wiki) what it can do for you.
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/AzureActiveDirectoryService.java
similarity index 87%
rename from src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java
rename to src/main/java/com/googlesource/gerrit/plugins/oauth/AzureActiveDirectoryService.java
index bdafd92..81dc53f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/AzureActiveDirectoryService.java
@@ -49,14 +49,16 @@
 import org.slf4j.LoggerFactory;
 
 @Singleton
-class Office365OAuthService implements OAuthServiceProvider {
-  private static final Logger log = LoggerFactory.getLogger(Office365OAuthService.class);
-  static final String CONFIG_SUFFIX = "-office365-oauth";
+class AzureActiveDirectoryService implements OAuthServiceProvider {
+  private static final Logger log = LoggerFactory.getLogger(AzureActiveDirectoryService.class);
+  static final String CONFIG_SUFFIX_LEGACY = "-office365-oauth";
+  static final String CONFIG_SUFFIX = "-azure-oauth";
+  private static final String AZURE_PROVIDER_PREFIX = "azure-oauth:";
   private static final String OFFICE365_PROVIDER_PREFIX = "office365-oauth:";
   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";
+  public 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;
@@ -65,13 +67,26 @@
   private final boolean useEmailAsUsername;
   private final String tenant;
   private final String clientId;
+  private String providerPrefix;
+  private final boolean linkOffice365Id;
 
   @Inject
-  Office365OAuthService(
+  AzureActiveDirectoryService(
       PluginConfigFactory cfgFactory,
       @PluginName String pluginName,
       @CanonicalWebUrl Provider<String> urlProvider) {
     PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX);
+    providerPrefix = AZURE_PROVIDER_PREFIX;
+
+    // ?: Did we find the client_id with the CONFIG_SUFFIX
+    if (cfg.getString(InitOAuth.CLIENT_ID) == null) {
+      // -> No, we did not find the client_id in the azure config so we should try the old legacy
+      // office365 section
+      cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX_LEGACY);
+      // We must also use the new provider prefix
+      providerPrefix = OFFICE365_PROVIDER_PREFIX;
+    }
+    this.linkOffice365Id = cfg.getBoolean(InitOAuth.LINK_TO_EXISTING_OFFICE365_ACCOUNT, false);
     this.canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/";
     this.useEmailAsUsername = cfg.getBoolean(InitOAuth.USE_EMAIL_AS_USERNAME, false);
     this.tenant = cfg.getString(InitOAuth.TENANT, DEFAULT_TENANT);
@@ -167,12 +182,13 @@
         if (useEmailAsUsername && !email.isJsonNull()) {
           login = email.getAsString().split("@")[0];
         }
+
         return new OAuthUserInfo(
-            OFFICE365_PROVIDER_PREFIX + id.getAsString() /*externalId*/,
+            providerPrefix + id.getAsString() /*externalId*/,
             login /*username*/,
             email == null || email.isJsonNull() ? null : email.getAsString() /*email*/,
             name == null || name.isJsonNull() ? null : name.getAsString() /*displayName*/,
-            null);
+            linkOffice365Id ? OFFICE365_PROVIDER_PREFIX + id.getAsString() : null);
       }
     } catch (ExecutionException | InterruptedException e) {
       throw new RuntimeException("Cannot retrieve user info resource", e);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/HttpModule.java
index 80bc605..b9517b2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/oauth/HttpModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/HttpModule.java
@@ -20,6 +20,7 @@
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.inject.Inject;
+import com.google.inject.ProvisionException;
 import com.google.inject.servlet.ServletModule;
 
 class HttpModule extends ServletModule {
@@ -99,11 +100,28 @@
           .to(KeycloakOAuthService.class);
     }
 
-    cfg = cfgFactory.getFromGerritConfig(pluginName + Office365OAuthService.CONFIG_SUFFIX);
+    boolean office365LegacyProviderBound = false;
+    cfg =
+        cfgFactory.getFromGerritConfig(
+            pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX_LEGACY);
     if (cfg.getString(InitOAuth.CLIENT_ID) != null) {
+      office365LegacyProviderBound = true;
       bind(OAuthServiceProvider.class)
-          .annotatedWith(Exports.named(Office365OAuthService.CONFIG_SUFFIX))
-          .to(Office365OAuthService.class);
+          .annotatedWith(Exports.named(AzureActiveDirectoryService.CONFIG_SUFFIX))
+          .to(AzureActiveDirectoryService.class);
+    }
+    cfg = cfgFactory.getFromGerritConfig(pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX);
+    if (cfg.getString(InitOAuth.CLIENT_ID) != null) {
+      // ?: Check if the legacy Office365 is already bound, we can only have one of these bound at
+      // one time
+      if (office365LegacyProviderBound) {
+        // -> Yes, the legacy Office365 is already bound and we are trying to bind the
+        // AzureActiveDirectoryService.CONFIG_SUFFIX at the same time.
+        throw new ProvisionException("Legacy Office365 OAuth provider is already bound!");
+      }
+      bind(OAuthServiceProvider.class)
+          .annotatedWith(Exports.named(AzureActiveDirectoryService.CONFIG_SUFFIX))
+          .to(AzureActiveDirectoryService.class);
     }
 
     cfg = cfgFactory.getFromGerritConfig(pluginName + AirVantageOAuthService.CONFIG_SUFFIX);
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 6f7ca01..3fbb2ca 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java
@@ -35,6 +35,7 @@
   static final String ROOT_URL = "root-url";
   static final String REALM = "realm";
   static final String TENANT = "tenant";
+  static final String LINK_TO_EXISTING_OFFICE365_ACCOUNT = "link-to-existing-office365-accounts";
   static final String SERVICE_NAME = "service-name";
   static String FIX_LEGACY_USER_ID_QUESTION = "Fix legacy user id, without oauth provider prefix?";
 
@@ -49,6 +50,7 @@
   private final Section dexOAuthProviderSection;
   private final Section keycloakOAuthProviderSection;
   private final Section office365OAuthProviderSection;
+  private final Section azureActiveDirectoryAuthProviderSection;
   private final Section airVantageOAuthProviderSection;
   private final Section phabricatorOAuthProviderSection;
 
@@ -74,7 +76,9 @@
     this.keycloakOAuthProviderSection =
         sections.get(PLUGIN_SECTION, pluginName + KeycloakOAuthService.CONFIG_SUFFIX);
     this.office365OAuthProviderSection =
-        sections.get(PLUGIN_SECTION, pluginName + Office365OAuthService.CONFIG_SUFFIX);
+        sections.get(PLUGIN_SECTION, pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX_LEGACY);
+    this.azureActiveDirectoryAuthProviderSection =
+        sections.get(PLUGIN_SECTION, pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX);
     this.airVantageOAuthProviderSection =
         sections.get(PLUGIN_SECTION, pluginName + AirVantageOAuthService.CONFIG_SUFFIX);
     this.phabricatorOAuthProviderSection =
@@ -159,12 +163,28 @@
       keycloakOAuthProviderSection.string("Keycloak Realm", REALM, null);
     }
 
-    boolean configureOffice365OAuthProvider =
-        ui.yesno(
-            isConfigured(office365OAuthProviderSection),
-            "Use Office365 OAuth provider for Gerrit login ?");
-    if (configureOffice365OAuthProvider) {
-      configureOAuth(office365OAuthProviderSection);
+    // ?: Are there legacy office365 already configured on the system?
+    if (isConfigured(office365OAuthProviderSection)) {
+      // -> Yes, this system has already configured the old legacy office365.
+      boolean configureOffice365OAuthProvider =
+          ui.yesno(
+              isConfigured(office365OAuthProviderSection),
+              "Use Office365 OAuth provider for Gerrit login ?");
+      if (configureOffice365OAuthProvider) {
+        configureOAuth(office365OAuthProviderSection);
+      }
+    }
+    // E-> No, we either are setting up on an new system or using the new azure config
+    else {
+      boolean configureAzureActiveDirectoryAuthProvider =
+          ui.yesno(
+              isConfigured(azureActiveDirectoryAuthProviderSection),
+              "Use Azure OAuth provider for Gerrit login ?");
+      if (configureAzureActiveDirectoryAuthProvider) {
+        configureOAuth(azureActiveDirectoryAuthProviderSection);
+        azureActiveDirectoryAuthProviderSection.string(
+            "Tenant", TENANT, AzureActiveDirectoryService.DEFAULT_TENANT);
+      }
     }
 
     boolean configureAirVantageOAuthProvider =
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index fec6ecb..78eb908 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -49,10 +49,18 @@
     client-secret = "<client-secret>"
     root-url = "<phabricator url>"
 
+  # The office365 has been renamed to azure and is deprecated.
   [plugin "@PLUGIN@-office365-oauth"]
     client-id = "<client-id>"
     client-secret = "<client-secret>"
     tenant = "<tenant (optional defaults to organizations if not set)>"
+
+  [plugin "@PLUGIN@-azure-oauth"]
+    client-id = "<client-id>"
+    client-secret = "<client-secret>"
+    tenant = "<tenant (optional defaults to organizations if not set)>"
+    link-to-existing-office365-accounts = true #Optional, if set will try to link old account with the @PLUGIN@-office365-oauth naming
+
 ```
 
 When one from the sections above is omitted, OAuth SSO is used.
@@ -228,26 +236,41 @@
 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,
+### Azure (previously named Office365)
+Were previously named Office365 but both `plugin.gerrit-oauth-provider-azure-oauth` and
+`plugin.gerrit-oauth-provider-office365-oauth` is supported by the Azure OAuth.
+When running *java gerrit.war init* it will check the existing config to see if it finds the old
+naming and use that during the init run, if it does not find the `office365-oauth` it will
+use the new `azure-oauth` naming.
+
+The client-id and client-secret for 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*
+By default, Azure OAuth will not set a username (used for ssh) and the user can choose one from the web ui
 can be used.
 ```
-plugin.gerrit-oauth-provider-office365-oauth.use-email-as-username = true
+plugin.gerrit-oauth-provider-azure-oauth.use-email-as-username = true
 ```
 
 ####Tenant
-The Gerrit OAuth plugin is default set to use the tenant `organizations` but a specific tenant can be used by 
+The Azure OAuth 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)
+See [Microsoft identity platform and OpenID Connect protocol](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc#fetch-the-openid-connect-metadata-document)
 ```
-plugin.gerrit-oauth-provider-office365-oauth.tenant = <tenant to use>
+plugin.gerrit-oauth-provider-azure-oauth.tenant = <tenant to use>
 ```
 
 Regardless of tenant all tokens will be checked that they contain the client_id set
-in the Gerrit OAuth plugin.
+in the Azure OAuth.
+
+####Migrating from Office365 naming
+If this where previously installed with the `office365-oauth` you can migrate to `azure-oauth` by setting the
+flag.
+```
+plugin.gerrit-oauth-provider-azure-oauth.link-to-existing-office365-accounts = true
+```
+This will try to link the old `office365-oauth` external id to the new `azure-oauth` external id automatically.
+Another option is to migrate these manually offline, see [External IDs](https://gerrit-review.googlesource.com/Documentation/config-accounts.html#external-ids)
+for more information.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java b/src/test/java/com/googlesource/gerrit/plugins/oauth/MicrosoftAzureActiveDirectory20ApiTest.java
similarity index 95%
rename from src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java
rename to src/test/java/com/googlesource/gerrit/plugins/oauth/MicrosoftAzureActiveDirectory20ApiTest.java
index a725167..a98348e 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/oauth/MicrosoftAzureActiveDirectory20ApiTest.java
@@ -21,7 +21,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
-public class Office365ApiTest {
+public class MicrosoftAzureActiveDirectory20ApiTest {
   private MicrosoftAzureActiveDirectory20Api api;
 
   @Before