@Override
  public String getAuthUrl() {
    Map<String, String> queryParams = new HashMap<>();
    queryParams.put("client_id", credentialsMap.get("id"));
    queryParams.put("redirect_uri", credentialsMap.get("redirect_uri"));
    queryParams.put("scope", "user:email");

    return AUTH_ENDPOINT + "?" + Helpers.stringifyParams(queryParams);
  }
  @Override
  public String authorize(String code, String error) throws Exception {
    Map<String, String> responseParams = new HashMap<>();

    if (error != null) {
      responseParams.put("error", error);
    } else {
      // get access token
      Map<String, String> postParams = new HashMap<>();
      postParams.put("code", code);
      postParams.put("client_id", credentialsMap.get("id"));
      postParams.put("client_secret", credentialsMap.get("secret"));
      postParams.put("redirect_uri", credentialsMap.get("redirect_uri"));

      String tokenResponse = Helpers.httpPost(TOKEN_ENDPOINT, postParams);
      HashMap<String, String> parsedTokenResponse = parseAccessToken(tokenResponse);

      // get required user info
      String userResponse = Helpers.httpGet(USER_ENDPOINT, parsedTokenResponse, null);
      HashMap<String, String> parsedUserResponse = parseUserInfo(userResponse);

      // generate access token for user
      AccessToken accessToken =
          generateAccessToken(
              PROVIDER_NAME,
              parsedTokenResponse.get("access_token"),
              parsedUserResponse.get("email"),
              parsedUserResponse.get("name"),
              parsedUserResponse.get("avatar"));

      responseParams.put("userId", accessToken.getUserId());
      responseParams.put("accessToken", accessToken.getValue());
    }

    return oauthCredentialsParser.getClientRedirectUri()
        + "?"
        + Helpers.stringifyParams(responseParams);
  }