code: /*
   * Copyright (c) 2022 Airbyte, Inc., all rights reserved.
   */
  
  package io.airbyte.oauth.flows;
  
  import com.fasterxml.jackson.databind.JsonNode;
  import com.google.common.annotations.VisibleForTesting;
  import io.airbyte.config.persistence.ConfigRepository;
  import io.airbyte.oauth.BaseOAuth2Flow;
  import java.io.IOException;
  import java.net.URISyntaxException;
  import java.net.http.HttpClient;
  import java.util.UUID;
  import java.util.function.Supplier;
  import org.apache.http.client.utils.URIBuilder;
  
  public class SlackOAuthFlow extends BaseOAuth2Flow {
  
    final String SLACK_CONSENT_URL_BASE = "https://slack.com/oauth/authorize";
    final String SLACK_TOKEN_URL = "https://slack.com/api/oauth.access";
  
    public SlackOAuthFlow(final ConfigRepository configRepository, final HttpClient httpClient) {
      super(configRepository, httpClient);
    }
  
    @VisibleForTesting
    public SlackOAuthFlow(final ConfigRepository configRepository, final HttpClient httpClient, final Supplier<String> stateSupplier) {
      super(configRepository, httpClient, stateSupplier);
    }
  
    /**
     * Depending on the OAuth flow implementation, the URL to grant user's consent may differ,
     * especially in the query parameters to be provided. This function should generate such consent URL
     * accordingly.
     */
    @Override
    protected String formatConsentUrl(final UUID definitionId,
                                      final String clientId,
                                      final String redirectUrl,
                                      final JsonNode inputOAuthConfiguration)
        throws IOException {
      try {
        return new URIBuilder(SLACK_CONSENT_URL_BASE)
            .addParameter("client_id", clientId)
            .addParameter("redirect_uri", redirectUrl)
            .addParameter("state", getState())
            .addParameter("scope", "read")
            .build().toString();
      } catch (final URISyntaxException e) {
        throw new IOException("Failed to format Consent URL for OAuth flow", e);
      }
    }
  
    /**
     * Returns the URL where to retrieve the access token from.
     */
    @Override
    protected String getAccessTokenUrl(final JsonNode inputOAuthConfiguration) {
      return SLACK_TOKEN_URL;
    }
  
  }
  