package io.corbel.iam.auth.provider;

import java.util.Map;

import org.springframework.social.NotAuthorizedException;
import org.springframework.social.connect.Connection;
import org.springframework.social.facebook.api.Facebook;
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.web.client.ResourceAccessException;

import io.corbel.iam.auth.OauthParams;
import io.corbel.iam.exception.ExchangeOauthCodeException;
import io.corbel.iam.exception.MissingOAuthParamsException;
import io.corbel.iam.exception.OauthServerConnectionException;
import io.corbel.iam.exception.UnauthorizedException;
import io.corbel.iam.model.Identity;
import io.corbel.iam.repository.IdentityRepository;

/**
 * @author Rubén Carrasco
 * 
 */
public class FacebookProvider extends AbstractOAuth2Provider<Facebook> {

    public FacebookProvider(IdentityRepository identityRepository) {
        super(identityRepository);
    }

    @Override
    public void setConfiguration(Map<String, String> configuration) {
        super.setConfiguration(configuration);
        connectionFactory = new FacebookConnectionFactory(configuration.get("clientId"), configuration.get("clientSecret"));
    }

    @Override
    public Identity getIdentity(OauthParams params, String oAuthService, String domain) throws UnauthorizedException,
            MissingOAuthParamsException, ExchangeOauthCodeException, OauthServerConnectionException {
        try {
            AccessGrant accessGrant = getAccessGrant(params);
            Connection<Facebook> connection = connectionFactory.createConnection(accessGrant);
            if (connection != null && !connection.hasExpired()) {
                Facebook facebook = connection.getApi();
                return identityRepository.findByOauthIdAndDomainAndOauthService(facebook.userOperations().getUserProfile().getId(), domain,
                        oAuthService);
            }
        } catch (ExchangeOauthCodeException e) {
            throw new UnauthorizedException("Unable to exchange code with Facebook: " + e.getMessage());
        } catch (ResourceAccessException e) {
            throw new OauthServerConnectionException("facebook", e.getMessage());
        } catch (NotAuthorizedException e) {
            throw new UnauthorizedException("Unable to verify identity with Facebook:  401 Unauthorized");
        } catch (Exception e) {
            throw new UnauthorizedException("Unable to verify identity with Facebook");
        }
        throw new UnauthorizedException("Unable to verify identity with Facebook");
    }

}

@@ -42,23 +42,445 @@
 ort 
-java.util.Map;%0A
+io.corbel.iam.auth.OauthParams;%0Aimport io.corbel.iam.exception.ExchangeOauthCodeException;%0Aimport io.corbel.iam.exception.MissingOAuthParamsException;%0Aimport io.corbel.iam.exception.OauthServerConnectionException;%0Aimport io.corbel.iam.exception.UnauthorizedException;%0Aimport io.corbel.iam.model.Identity;%0Aimport io.corbel.iam.repository.IdentityRepository;%0A%0Aimport java.util.Map;%0A%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0Aimp
@@ -845,373 +845,8 @@
 n;%0A%0A
-import io.corbel.iam.auth.OauthParams;%0Aimport io.corbel.iam.exception.ExchangeOauthCodeException;%0Aimport io.corbel.iam.exception.MissingOAuthParamsException;%0Aimport io.corbel.iam.exception.OauthServerConnectionException;%0Aimport io.corbel.iam.exception.UnauthorizedException;%0Aimport io.corbel.iam.model.Identity;%0Aimport io.corbel.iam.repository.IdentityRepository;%0A%0A
 /**%0A
@@ -953,16 +953,104 @@
 ook%3E %7B%0A%0A
+    private static final Logger LOG = LoggerFactory.getLogger(FacebookProvider.class);%0A%0A
     publ
@@ -2594,32 +2594,113 @@
 (Exception e) %7B%0A
+            LOG.error(%22Unexpected error when verify identity with Facebook%22, e);%0A
             thro
@@ -2773,32 +2773,92 @@
 ok%22);%0A        %7D%0A
+        LOG.error(%22Facebook connection failed or expired%22);%0A
         throw ne

add error traces