[Java] Access ImgUr API Version 3 Via Scribe

About

I'm trying to access ImgUr API version 3 with Java, since I want to implement an platform that aggerate all of my photos from different photo hosting service website.

Although we have a convenient OAuth library called Scribe, unfortunately, the built-in ImgUr API service class in Scribe is already obsolete and wont work on ImgUr API version 3.

Since Scribe has a really great design and quite flexible, I've implemented a Scribe service class that could work on ImgUr API version 3.

Code

You could look the code at my Pull Request at GitHub, it's just two extra Java classes.

Because the code is very short and Scribe could plug them in directly, so you could simply copy & paste this two files into your project, and following the example to access ImgUr API version 3.

package org.scribe.builder.api;

import org.scribe.model.OAuthConfig;
import org.scribe.oauth.OAuthService;
import org.scribe.oauth.OAuthImgUr3Impl;

import org.scribe.model.Verb;
import org.scribe.extractors.JsonTokenExtractor;
import org.scribe.extractors.AccessTokenExtractor;

/**
 * ImgUr API ver3 (OAuth 2)
 *
 * @author Brian Hsu
 *
 * @see <a href="http://api.imgur.com/">ImgUr API</a>
 */
public class ImgUr3Api extends DefaultApi20 {

  private static final String authorizeURL = "https://api.imgur.com/oauth2/authorize";

  private boolean isOOB(OAuthConfig config) {
    return "oob".equals(config.getCallback());
  }

  @Override
  public Verb getAccessTokenVerb() {
    return Verb.POST;
  }

  @Override
  public AccessTokenExtractor getAccessTokenExtractor() {
    return new JsonTokenExtractor();
  }

  @Override
  public String getAccessTokenEndpoint() {
    return "https://api.imgur.com/oauth2/token";
  }

  @Override
  public String getAuthorizationUrl(OAuthConfig config) {
    String apiKey = config.getApiKey();
    if (isOOB(config)) {
      return String.format("%s?client_id=%s&response_type=pin", authorizeURL, apiKey);
    } else {
      return String.format("%s?client_id=%s&response_type=code", authorizeURL, apiKey);
    }
  }

  @Override
  public OAuthService createService(OAuthConfig config) {
    return new OAuthImgUr3Impl(this, config);
  }
}
package org.scribe.oauth;

import org.scribe.builder.api.DefaultApi20;

import org.scribe.model.OAuthConfig;
import org.scribe.model.OAuthConstants;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;

public class OAuthImgUr3Impl extends OAuth20ServiceImpl {

  private DefaultApi20 api;
  private OAuthConfig config;

  public OAuthImgUr3Impl(DefaultApi20 api, OAuthConfig config) {
    super(api, config);
    this.api = api;
    this.config = config;
  }

  private boolean isOOB(OAuthConfig config) {
    return "oob".equals(config.getCallback());
  }

  @Override
  public Token getAccessToken(Token requestToken, Verifier verifier) {

    OAuthRequest request = new OAuthRequest(
      api.getAccessTokenVerb(),
      api.getAccessTokenEndpoint()
    );

    String grantType = isOOB(config) ? "pin" : "authorization_code";

    // ImgUr API ver 3 using POST to get token, and we need pass
    // parameters using Body parameter, query string will not work.
    request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
    request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
    request.addBodyParameter("grant_type", grantType);
    request.addBodyParameter("pin", verifier.getValue());

    Response response = request.send();

    return api.getAccessTokenExtractor().extract(response.getBody());
  }

  @Override
  public void signRequest(Token accessToken, OAuthRequest request) {

    if (accessToken != null) {
      request.addHeader("Authorization", "Bearer " + accessToken.getToken());
    } else {
      request.addHeader("Authorization", "Client-ID " + config.getApiKey());
    }
  }

}

回響