content: package org.pmiops.workbench.captcha;
  
  import jakarta.inject.Provider;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  import java.util.stream.Collectors;
  import org.pmiops.workbench.captcha.api.CaptchaApi;
  import org.pmiops.workbench.captcha.model.CaptchaVerificationResponse;
  import org.pmiops.workbench.config.WorkbenchConfig;
  import org.pmiops.workbench.google.CloudStorageClient;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Service;
  
  /** Service to verify Captcha */
  @Service
  public class CaptchaVerificationServiceImpl implements CaptchaVerificationService {
  
    final String urlPattern = "https://%s/login";
  
    // In case of environments using automation test like  local/Test etc we will be using google
    // captcha test keys
    // https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha.-what-should-i-do
    // which will send the following as the hostName if successful
    final String googleTestHost = "testkey.google.com";
  
    private CloudStorageClient cloudStorageClient;
    final Provider<WorkbenchConfig> configProvider;
    private Provider<CaptchaApi> captchaApiProvider;
  
    private static final Logger log =
        Logger.getLogger(CaptchaVerificationServiceImpl.class.getName());
  
    @Autowired
    public CaptchaVerificationServiceImpl(
        CloudStorageClient cloudStorageClient,
        jakarta.inject.Provider<WorkbenchConfig> configProvider,
        jakarta.inject.Provider<CaptchaApi> captchaApiProvider) {
      this.cloudStorageClient = cloudStorageClient;
      this.configProvider = configProvider;
      this.captchaApiProvider = captchaApiProvider;
    }
  
    /**
     * Calls google api to verify Captcha Response by sending the captcha Server key associated with
     * host and the token generated by the user response on front end. Returns true if valid else
     * false
     *
     * @param responseToken
     * @return if Captcha is valid
     */
    @Override
    public boolean verifyCaptcha(String responseToken) throws ApiException {
      CaptchaVerificationResponse response =
          captchaApiProvider.get().verify(cloudStorageClient.getCaptchaServerKey(), responseToken);
      if (!response.isSuccess()) {
        log.log(
            Level.WARNING,
            String.format(
                "Exception while verifying captcha%s",
                response.getErrorCodes().stream()
                    .map(errorCodes -> errorCodes.getValue())
                    .collect(Collectors.joining(","))));
        return false;
      }
      String captchaHostname = response.getHostname();
      String uiUrl = configProvider.get().admin.loginUrl;
      boolean usingTestCaptcha = configProvider.get().captcha.useTestCaptcha;
      boolean captchaHostNameMatchUI = false;
  
      // Production/Stable should  not use google test Key and the domainName should match with the
      // one return from Captcha Response
      if (!usingTestCaptcha) {
        // check if the UI URL has the host as send by Captcha Response
        captchaHostNameMatchUI = String.format(urlPattern, captchaHostname).equals(uiUrl);
      } else {
        // Captcha returns host as testkey.google.com, if test keys are used
        captchaHostNameMatchUI = captchaHostname.equals(googleTestHost);
      }
      if (!captchaHostNameMatchUI) {
        log.log(
            Level.SEVERE, String.format("Captcha Host Name %s does not match UI", captchaHostname));
      }
      return response.isSuccess() && captchaHostNameMatchUI;
    }
  }
  