<groupId>de.juplo</groupId>
- <artifactId>facebook-utils</artifactId>
- <name>Juplo - Facebook Utils</name>
- <description>Collection of usefull classes for communicating with the Facebook-Graph-API</description>
- <version>2.5.1-SNAPSHOT</version>
+ <artifactId>facebook-errors</artifactId>
+ <name>Juplo - Facebook-Errors</name>
+ <description>Helper-Classes to handle errors, thrown by the Graph-API from Facebook</description>
+ <version>2.5.0-SNAPSHOT</version>
<packaging>jar</packaging>
- <url>http://www.juplo.de/facebook-utils</url>
+ <url>http://www.juplo.de/facebook-errors</url>
<prerequisites>
</licenses>
<scm>
- <connection>scm:git:http://juplo.de/git/facebook-utils</connection>
- <developerConnection>scm:git:ssh://juplo.de:/var/lib/git/juplo/facebook-utils</developerConnection>
- <url>http://juplo.de/gitweb/?p=facebook-utils;a=summary</url>
+ <connection>scm:git:http://juplo.de/git/facebook-errors</connection>
+ <developerConnection>scm:git:ssh://juplo.de:/var/lib/git/juplo/facebook-errors</developerConnection>
+ <url>http://juplo.de/gitweb/?p=facebook-errors;a=summary</url>
</scm>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- used versions -->
- <commons-codec.version>1.7</commons-codec.version>
- <aspectj.version>1.8.5</aspectj.version>
<jackson.version>2.6.2</jackson.version>
<junit.version>4.12</junit.version>
<logback.version>1.1.3</logback.version>
- <servlet-api.version>3.0.1</servlet-api.version>
<slf4j.version>1.7.12</slf4j.version>
<springframework.version>4.2.1.RELEASE</springframework.version>
- <spring-security.version>4.0.2.RELEASE</spring-security.version>
- <spring-security-oauth2.version>2.0.8.RELEASE</spring-security-oauth2.version>
</properties>
<dependencies>
<!-- Spring -->
- <dependency>
- <groupId>org.springframework.security.oauth</groupId>
- <artifactId>spring-security-oauth2</artifactId>
- <version>${spring-security-oauth2.version}</version>
- <exclusions>
- <exclusion>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-expression</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-config</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-core</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-web</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${jackson.version}</version>
</dependency>
- <!-- Needed to compile agains spring-security-oauth2 -->
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-core</artifactId>
- <version>${spring-security.version}</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-expression</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <!-- AspectJ -->
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjrt</artifactId>
- <version>${aspectj.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- commons-codec -->
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- <version>${commons-codec.version}</version>
- </dependency>
-
- <!-- Servlet -->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>${servlet-api.version}</version>
- <scope>provided</scope>
- </dependency>
-
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<distributionManagement>
<site>
<id>www.juplo.de</id>
- <url>scp://juplo.de/var/www/juplo/facebook-utils-${project.version}</url>
+ <url>scp://juplo.de/var/www/juplo/facebook-errors-${project.version}</url>
</site>
</distributionManagement>
+++ /dev/null
-package de.juplo.facebook;
-
-
-import de.juplo.facebook.errors.GraphApiErrorHandler;
-import de.juplo.facebook.token.SignedRequestAwareAuthorizationCodeAccessTokenProvider;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import javax.annotation.PostConstruct;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.oauth2.client.OAuth2RestTemplate;
-import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
-import org.springframework.security.oauth2.client.token.AccessTokenProvider;
-import org.springframework.security.oauth2.client.token.AccessTokenProviderChain;
-import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider;
-import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitAccessTokenProvider;
-import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider;
-
-
-
-/**
- * This class injects the facebook-utils into the spring-oauth2-configuration
- *
- * @author kai
- */
-@Configuration
-public class FacebookUtils
-{
- private final Logger log = LoggerFactory.getLogger(FacebookUtils.class);
-
-
- @Autowired(required=false)
- private List<AccessTokenProvider> accessTokenProviderChain;
-
-
- @PostConstruct
- public void init()
- {
- if (accessTokenProviderChain == null)
- {
- log.info("no AccessTokenProviderChain configured, creating default-chain");
- accessTokenProviderChain =
- Arrays.<AccessTokenProvider> asList(
- new ImplicitAccessTokenProvider(),
- new ResourceOwnerPasswordAccessTokenProvider(),
- new ClientCredentialsAccessTokenProvider()
- );
- }
- }
-
-
- @Bean
- public BeanPostProcessor getBeanPostProcessor(final String clientSecret)
- {
- log.debug("createing new instance of BeanPostProcessor");
- return new BeanPostProcessor() {
-
- @Override
- public Object postProcessBeforeInitialization(
- Object bean,
- String beanName
- )
- throws
- BeansException
- {
- if (bean instanceof OAuth2RestTemplate)
- {
- log.info("injecting signed_request-aware AccessTokenProviderChain");
- OAuth2RestTemplate template = (OAuth2RestTemplate)bean;
- List<AccessTokenProvider> chain =
- new LinkedList<>(accessTokenProviderChain);
- SignedRequestAwareAuthorizationCodeAccessTokenProvider provider =
- new SignedRequestAwareAuthorizationCodeAccessTokenProvider();
- provider.setSecret(clientSecret);
- chain.add(provider);
- template.setAccessTokenProvider(new AccessTokenProviderChain(chain));
- log.info("injecting GraphApiErrorHandler");
- template.setErrorHandler(
- new GraphApiErrorHandler(
- (OAuth2ErrorHandler)template.getErrorHandler()
- )
- );
- }
-
- return bean;
- }
-
- @Override
- public Object postProcessAfterInitialization(
- Object bean,
- String beanName
- )
- throws
- BeansException
- {
- return bean;
- }
- };
- }
-}
+++ /dev/null
-package de.juplo.facebook.aspects;
-
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @author Kai Moritz
- */
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Sanitize
-{
- int length() default 255; // in accordance to @Column(length)
- boolean fail() default false;
-}
+++ /dev/null
-package de.juplo.facebook.aspects;
-
-
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-/**
- * @author Kai Moritz
- */
-@Aspect
-public class SanitizeAspect
-{
- private static final Logger log =
- LoggerFactory.getLogger(SanitizeAspect.class);
-
-
- /**
- * This method sanitizes the given string in all means:
- * <ul>
- * <li>It removes leading and trailing whitspace.</li>
- * <li>It removes characters, that are not allowed in the XML-output</li>
- * <li>It checks the allowed length of the string</li>
- * </ul>
- *
- * This method ensures that the output String has only
- * valid XML unicode characters as specified by the
- * XML 1.0 standard. For reference, please see
- * <a href="http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char">the
- * standard</a>. This method will return an empty
- * String if the input is null or empty.
- *
- * @param jp The join-point captured by AspectJ.
- * @param in The String whose non-valid characters we want to remove.
- * @param sanitize The annotation, the field was marked with.
- * @see <a href="http://blog.mark-mclaren.info/2007/02/invalid-xml-characters-when-valid-utf8_5873.html">Invalid XML Characters: when valid UTF8 does not mean valid XML</a>
- * @see <a href="http://up-download.de/up/docs/werkstatt/de/intrexx-werkstatt-ungueltige-zeichen-in-eingabefeldern-abfangen.pdf">Ungültige Zeichen in Eingabefeldern abfangen</a>
- */
- @Around("set(String *) && args(in) && @annotation(sanitize)")
- public void sanitize(
- ProceedingJoinPoint jp,
- String in,
- Sanitize sanitize
- )
- throws Throwable
- {
- if (in == null)
- {
- jp.proceed(new Object[] { null });
- return;
- }
-
- in = in.trim();
- if ("".equals(in))
- {
- jp.proceed(new Object[] { null });
- return;
- }
-
- StringBuilder out = new StringBuilder(); // Used to hold the output.
- char current; // Used to reference the current character.
-
- for (int i = 0; i < in.length(); i++)
- {
- current = in.charAt(i); // NOTE: No IndexOutOfBoundsException caught here; it should not happen.
- if ((current == 0x9) ||
- (current == 0xA) ||
- (current == 0xD) ||
- ((current >= 0x20) && (current <= 0xD7FF)) ||
- ((current >= 0xE000) && (current <= 0xFFFD)) ||
- ((current >= 0x10000) && (current <= 0x10FFFF)))
- out.append(current);
- }
- if (out.length() > sanitize.length())
- {
- log.error(
- "Maximum length for attribute {} exceeded: should={}, was={}",
- jp.getSignature().getName(),
- sanitize.length(),
- out.length()
- );
- if (sanitize.fail())
- throw new RuntimeException("String is longer than " + sanitize.length());
- else
- out.setLength(sanitize.length());
- }
- jp.proceed(new Object[] { out.toString() });
- }
-}
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
*
* @author Kai Moritz
*/
-public class GraphApiException extends OAuth2Exception
+public class GraphApiException extends RuntimeException
{
public enum Type { OAuthException, GraphMethodException }
case 100: return new UnsupportedGetRequestException(error);
case 102: return new UserAccessTokenRequiredException(error);
case 104: return new AccessTokenRequiredException(error);
+ case 200: // TODO: curl -i -X POST -d "message=%C3%9Cberschrieben" -d "access_token=EAACEdEose0cBAMeuejNdjqZAFZAQZBjB6Ah9z80GLQz8BMlnZBKqzTBZB40CgjQGbNq7E8YdCp1VGMcZBZAfKNOWTTvzMnb8ptaoHygVz44MyEiHiOOf7MDp43guIjhOdK1wZBE6AyZBEMzI3G6jl0GsZBZChNu9LKbK9S4OpZCIswINAQZDZD" "https://graph.facebook.com/v2.5/100000503618294_1341539019206206"
+ // {"error":{"message":"(#200) Requires extended permission: publish_actions","type":"OAuthException","code":200,"fbtrace_id":"HuJNKjAHZBo"}}
// 200..299: permission errors
// 300..399: data editing errors
// 400..449: authentication error
+++ /dev/null
-package de.juplo.facebook.token;
-
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import org.apache.commons.codec.binary.Base64;
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
-import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
-import org.springframework.security.oauth2.client.token.AccessTokenRequest;
-import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider;
-import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
-import org.springframework.security.oauth2.common.OAuth2AccessToken;
-
-
-/**
- * This class extends {@link AuthorizationCodeAccessTokenProvider} and adds
- * support for signed requests, which are issued by Facebook, if the Canvas-
- * or Tab-Page of a Facebook-App is accessed for the first time.
- *
- * @author Kai Moritz
- */
-public class SignedRequestAwareAuthorizationCodeAccessTokenProvider
- extends AuthorizationCodeAccessTokenProvider
-{
- private final Logger log =
- LoggerFactory.getLogger(SignedRequestAwareAuthorizationCodeAccessTokenProvider.class);
- private final static Pattern pattern =
- Pattern.compile("([a-zA-Z0-9_-]+)\\.([a-zA-Z0-9_-]+)");
-
- public final static String PARAM_SIGNED_REQUEST = "signed_request";
-
-
- private String secret;
- private ObjectMapper objectMapper;
-
-
- @Override
- public OAuth2AccessToken obtainAccessToken(
- OAuth2ProtectedResourceDetails details,
- AccessTokenRequest parameters
- )
- {
- try
- {
- return super.obtainAccessToken(details, parameters);
- }
- catch (UserRedirectRequiredException redirect)
- {
- log.debug("no valid access-token available: checking for signed request");
-
- if (!parameters.containsKey(PARAM_SIGNED_REQUEST))
- {
- log.info(
- "parameter " + PARAM_SIGNED_REQUEST + " is not present"
- );
- throw redirect;
- }
-
- String signed_request = parameters.get(PARAM_SIGNED_REQUEST).get(0);
-
- Matcher matcher = pattern.matcher(signed_request);
- if (!matcher.matches())
- {
- log.error("invalid signed_request: {}", signed_request);
- throw redirect;
- }
-
- String signature = matcher.group(1);
- String rawdata = matcher.group(2);
-
- String data;
- try
- {
- data = new String(Base64.decodeBase64(rawdata), "UTF-8");
- log.debug("JSON-data: {}", data);
- }
- catch (UnsupportedEncodingException e)
- {
- log.error("error while decoding data: {}", e.getMessage());
- throw redirect;
- }
-
- JsonNode json;
- try
- {
- json = objectMapper.readTree(data);
- }
- catch (IOException e)
- {
- log.error("error \"{}\" while parsing JSON-data: {}", e, data);
- throw redirect;
- }
-
- String algorithm = "";
- try
- {
- algorithm = json.get("algorithm").asText();
- }
- catch (NullPointerException e) {}
- if (algorithm.isEmpty())
- {
- log.error("field \"algorithm\" is missing: {}", data);
- throw redirect;
- }
- algorithm = algorithm.replaceAll("-", "");
-
- String check;
- try
- {
- SecretKeySpec key = new SecretKeySpec(secret.getBytes("UTF-8"), algorithm);
- Mac mac = Mac.getInstance(algorithm);
- mac.init(key);
- byte[] hmacData = mac.doFinal(rawdata.getBytes("UTF-8"));
- check = new String(Base64.encodeBase64URLSafe(hmacData), "UTF-8");
- }
- catch (
- UnsupportedEncodingException |
- NoSuchAlgorithmException |
- InvalidKeyException |
- IllegalStateException e
- )
- {
- log.error("signature check failed!", e);
- throw redirect;
- }
- if (!check.equals(signature))
- {
- log.error("signature does not match!");
- throw redirect;
- }
-
- /**
- * Extract additional information and store it in the token
- * See:
- * https://developers.facebook.com/docs/reference/login/signed-request/
- * TODO:
- * - Attribute "code"
- */
- Map<String,Object> additionalInformation = new HashMap<>();
- try
- {
- additionalInformation.put(
- "issued_at",
- new Date(json.get("issued_at").getLongValue()*1000L)
- );
- Map<String,Object> user = new HashMap<>();
- user.put(
- "country",
- json.get("user").get("country").asText()
- );
- user.put(
- "locale",
- json.get("user").get("locale").asText()
- );
- user.put(
- "age_min",
- json.get("user").get("age").get("min").getNumberValue()
- );
- if (json.get("user") != null && json.get("user").get("max") != null)
- user.put(
- "age_max",
- json.get("user").get("age").get("max").getNumberValue()
- );
- additionalInformation.put("user", user);
- if (json.get("app_data") != null)
- additionalInformation.put("app_data", json.get("app_data").asText());
- if (json.get("page") != null)
- {
- Map<String,Object> page = new HashMap<>();
- page.put("id", json.get("page").get("id").asText());
- page.put("liked", json.get("page").get("liked").asBoolean());
- page.put("admin", json.get("page").get("admin").asBoolean());
- additionalInformation.put("page", page);
- }
- }
- catch (NullPointerException e)
- {
- log.warn("expected additional data is missing: {}", data);
- }
-
- DefaultOAuth2AccessToken token = null;
- try
- {
- String value = json.get("oauth_token").asText();
- if (value.isEmpty())
- {
- log.error("field \"oauth_token\" is missing: {}", data);
- throw redirect;
- }
- token = new DefaultOAuth2AccessToken(value);
- token.setExpiration(new Date(json.get("expires").getLongValue()*1000L));
-
- additionalInformation.put(
- "user_id",
- json.get("user_id").asText()
- );
-
- token.setAdditionalInformation(additionalInformation);
- }
- catch (NullPointerException e)
- {
- if (token == null)
- {
- log.error("field \"oauth_token\" is missing: {}", data);
- throw redirect;
- }
- else
- log.warn("expected additional data is missing: {}", data);
- }
-
- return token;
- }
- }
-
-
- public String getSecret()
- {
- return secret;
- }
-
- public void setSecret(String secret)
- {
- this.secret = secret;
- }
-
- public ObjectMapper getObjectMapper()
- {
- return objectMapper;
- }
-
- public void setObjectMapper(ObjectMapper objectMapper)
- {
- this.objectMapper = objectMapper;
- }
-}
import de.juplo.facebook.errors.GraphApiException.Type;
-import java.util.Date;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.Resource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.oauth2.client.OAuth2RestTemplate;
-import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
-import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
-import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException;
-import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
-import org.springframework.security.oauth2.client.token.AccessTokenProvider;
-import org.springframework.security.oauth2.client.token.AccessTokenRequest;
-import org.springframework.security.oauth2.common.OAuth2AccessToken;
-import static org.springframework.security.oauth2.common.OAuth2AccessToken.OAUTH2_TYPE;
-import org.springframework.security.oauth2.common.OAuth2RefreshToken;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestTemplate;
*
* @author Kai Moritz
*/
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(
- locations = {
- "classpath:/spring/test-facebook-error-handler.xml"
- })
public class GraphApiErrorHandlerTest
{
private static final Logger log =
LoggerFactory.getLogger(GraphApiErrorHandlerTest.class);
- @Resource
- private OAuth2RestTemplate clientTemplate;
-
+ private RestTemplate clientTemplate;
private MockClientHttpRequestFactory requestFactory;
catch(UnknownErrorException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(1), e.getCode());
assertEquals("An unknown error has occurred.", e.getMessage());
assertEquals(Type.OAuthException, e.getType());
catch(UnexpectedErrorException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(2), e.getCode());
assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage());
assertEquals(Type.OAuthException, e.getType());
catch(PageMigratedException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(21), e.getCode());
assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage());
assertEquals(Type.OAuthException, e.getType());
catch(UnsupportedGetRequestException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(100), e.getCode());
assertEquals("Unsupported get request.", e.getMessage());
assertEquals(Type.GraphMethodException, e.getType());
catch(UserAccessTokenRequiredException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(102), e.getCode());
assertEquals("A user access token is required to request this resource.", e.getMessage());
assertEquals(Type.OAuthException, e.getType());
catch(AccessTokenRequiredException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(104), e.getCode());
assertEquals("An access token is required to request this resource.", e.getMessage());
assertEquals(Type.OAuthException, e.getType());
catch(RateExceededException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(613), e.getCode());
assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage());
assertEquals(Type.OAuthException, e.getType());
catch(CallbackVerificationFailedException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(2200), e.getCode());
assertEquals("(#2200) callback verification failed: ", e.getMessage());
assertEquals(Type.OAuthException, e.getType());
catch(GraphApiException e)
{
log.debug("{}", e.toString());
- assertEquals("invalid_request", e.getOAuth2ErrorCode());
assertEquals(new Integer(999999999), e.getCode());
assertEquals("This error does not exist.", e.getMessage());
try
clientTemplate.setRequestFactory(requestFactory);
clientTemplate.setErrorHandler(
- new GraphApiErrorHandler(
- (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
- )
+ new GraphApiErrorHandler(clientTemplate.getErrorHandler())
);
-
- clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
- {
- @Override
- public OAuth2AccessToken obtainAccessToken(
- OAuth2ProtectedResourceDetails details,
- AccessTokenRequest parameters
- )
- throws
- UserRedirectRequiredException,
- UserApprovalRequiredException,
- AccessDeniedException
- {
- return new OAuth2AccessToken() {
-
- @Override
- public Map<String, Object> getAdditionalInformation()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public Set<String> getScope()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public OAuth2RefreshToken getRefreshToken()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public String getTokenType()
- {
- return OAUTH2_TYPE;
- }
-
- @Override
- public boolean isExpired()
- {
- return false;
- }
-
- @Override
- public Date getExpiration()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public int getExpiresIn()
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public String getValue()
- {
- return "ANY";
- }
- };
- }
-
- @Override
- public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
- {
- return true;
- }
-
- @Override
- public OAuth2AccessToken refreshAccessToken(
- OAuth2ProtectedResourceDetails resource,
- OAuth2RefreshToken refreshToken,
- AccessTokenRequest request
- )
- throws
- UserRedirectRequiredException
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)
- {
- return false;
- }
- });
}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- http://www.springframework.org/schema/security/oauth2
- http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
- ">
-
-
- <oauth:rest-template id="template" resource="resource"/>
- <oauth:resource
- id="resource"
- type="client_credentials"
- client-id="EGAL"
- client-secret="EGAL"
- authentication-scheme="query"
- access-token-uri="https://graph.facebook.com/v2.0/oauth/access_token"
- token-name="oauth_token"
- scope="read_stream"
- />
-
-</beans>