diff --git a/social/pom.xml b/social/pom.xml
index bb982ebf33..435b8e399a 100755
--- a/social/pom.xml
+++ b/social/pom.xml
@@ -31,30 +31,26 @@
org.jboss.spec.javax.ejb
jboss-ejb-api_3.2_spec
- provided
1.0.0.Alpha2
+ provided
com.google.api-client
google-api-client
- provided
com.google.http-client
google-http-client-jackson
- provided
com.google.apis
google-api-services-oauth2
- provided
org.twitter4j
twitter4j-core
- provided
diff --git a/social/src/main/java/org/keycloak/social/IdentityProvider.java b/social/src/main/java/org/keycloak/social/IdentityProvider.java
index 202e82da78..c48d4fa2f9 100644
--- a/social/src/main/java/org/keycloak/social/IdentityProvider.java
+++ b/social/src/main/java/org/keycloak/social/IdentityProvider.java
@@ -37,7 +37,7 @@ public interface IdentityProvider {
String getId();
@XmlTransient
- URI getAuthUrl(IdentityProviderCallback callback);
+ URI getAuthUrl(IdentityProviderCallback callback) throws IdentityProviderException;
String getName();
@@ -45,6 +45,6 @@ public interface IdentityProvider {
boolean isCallbackHandler(IdentityProviderCallback callback);
@XmlTransient
- User processCallback(IdentityProviderCallback callback);
+ User processCallback(IdentityProviderCallback callback) throws IdentityProviderException;
}
diff --git a/social/src/main/java/org/keycloak/social/IdentityProviderErrors.java b/social/src/main/java/org/keycloak/social/IdentityProviderErrors.java
new file mode 100644
index 0000000000..ed5ddb0dbc
--- /dev/null
+++ b/social/src/main/java/org/keycloak/social/IdentityProviderErrors.java
@@ -0,0 +1,6 @@
+package org.keycloak.social;
+
+public class IdentityProviderErrors {
+ public static final String INVALID_PROVIDER = "invalid_provider";
+ public static final String PROVIDER_ERROR = "provider_error";
+}
diff --git a/social/src/main/java/org/keycloak/social/IdentityProviderException.java b/social/src/main/java/org/keycloak/social/IdentityProviderException.java
new file mode 100644
index 0000000000..6d011e29cb
--- /dev/null
+++ b/social/src/main/java/org/keycloak/social/IdentityProviderException.java
@@ -0,0 +1,11 @@
+package org.keycloak.social;
+
+public class IdentityProviderException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public IdentityProviderException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/social/src/main/java/org/keycloak/social/google/GoogleProvider.java b/social/src/main/java/org/keycloak/social/google/GoogleProvider.java
index cb180c9bc7..9530278f68 100644
--- a/social/src/main/java/org/keycloak/social/google/GoogleProvider.java
+++ b/social/src/main/java/org/keycloak/social/google/GoogleProvider.java
@@ -24,9 +24,9 @@ package org.keycloak.social.google;
import java.net.URI;
import java.util.UUID;
-import org.jboss.resteasy.logging.Logger;
import org.keycloak.social.IdentityProvider;
import org.keycloak.social.IdentityProviderCallback;
+import org.keycloak.social.IdentityProviderException;
import org.picketlink.idm.model.SimpleUser;
import org.picketlink.idm.model.User;
@@ -46,8 +46,6 @@ public class GoogleProvider implements IdentityProvider {
private static final JacksonFactory JSON_FACTORY = new JacksonFactory();
- private static final Logger log = Logger.getLogger(GoogleProvider.class);
-
private static final NetHttpTransport TRANSPORT = new NetHttpTransport();
@Override
@@ -81,7 +79,7 @@ public class GoogleProvider implements IdentityProvider {
}
@Override
- public User processCallback(IdentityProviderCallback callback) {
+ public User processCallback(IdentityProviderCallback callback) throws IdentityProviderException {
String code = callback.getQueryParam("code");
try {
@@ -109,8 +107,7 @@ public class GoogleProvider implements IdentityProvider {
return user;
} catch (Exception e) {
- log.error("Failed to process callback", e);
- return null;
+ throw new IdentityProviderException(e);
}
}
diff --git a/social/src/main/java/org/keycloak/social/resources/SocialApplication.java b/social/src/main/java/org/keycloak/social/resources/SocialApplication.java
new file mode 100644
index 0000000000..a332b5a4aa
--- /dev/null
+++ b/social/src/main/java/org/keycloak/social/resources/SocialApplication.java
@@ -0,0 +1,9 @@
+package org.keycloak.social.resources;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("social/api")
+public class SocialApplication extends Application {
+
+}
diff --git a/social/src/main/java/org/keycloak/social/resources/SocialResource.java b/social/src/main/java/org/keycloak/social/resources/SocialResource.java
index ec8c5dec45..4d5c174e1d 100644
--- a/social/src/main/java/org/keycloak/social/resources/SocialResource.java
+++ b/social/src/main/java/org/keycloak/social/resources/SocialResource.java
@@ -41,8 +41,11 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
+import org.jboss.resteasy.logging.Logger;
import org.keycloak.social.IdentityProvider;
import org.keycloak.social.IdentityProviderCallback;
+import org.keycloak.social.IdentityProviderErrors;
+import org.keycloak.social.IdentityProviderException;
import org.keycloak.social.IdentityProviderState;
import org.keycloak.social.util.UriBuilder;
import org.picketlink.idm.model.Attribute;
@@ -51,9 +54,11 @@ import org.picketlink.idm.model.User;
/**
* @author Stian Thorgersen
*/
-@Path("social")
+@Path("")
public class SocialResource {
+ private static final Logger log = Logger.getLogger(SocialResource.class);
+
// TODO This is just temporary - need to either save state variables somewhere they can be flushed after a timeout, or
// alternatively they could be saved in http session, but that is probably not a good idea
private static final Map states = new HashMap();
@@ -89,9 +94,12 @@ public class SocialResource {
callback.setProviderState(getProviderState(provider));
if (provider.isCallbackHandler(callback)) {
- User user = provider.processCallback(callback);
- if (user == null) {
- break;
+ User user = null;
+ try {
+ user = provider.processCallback(callback);
+ } catch (IdentityProviderException e) {
+ log.warn("Failed to process callback", e);
+ redirectToLogin(application, IdentityProviderErrors.PROVIDER_ERROR);
}
String providerUsername = user.getLoginName();
@@ -135,6 +143,7 @@ public class SocialResource {
@GET
@Path("providers")
+ @Produces(MediaType.APPLICATION_JSON)
public List getProviders() {
List providers = new LinkedList();
Iterator itr = ServiceRegistry.lookupProviders(IdentityProvider.class);
@@ -170,13 +179,12 @@ public class SocialResource {
}
private Response redirectToLogin(String application, String error) {
- URI uri = new UriBuilder(headers, uriInfo, "login?application=" + application + "&error=login_failed").build();
+ URI uri = new UriBuilder(headers, uriInfo, "sdk/api/" + application + "/login").setQueryParam("error", error).build();
return Response.seeOther(uri).build();
}
@GET
@Path("{application}/auth/{provider}")
- @Produces(MediaType.TEXT_HTML)
public Response redirectToProviderAuth(@PathParam("application") String application,
@PathParam("provider") String providerId) {
Iterator itr = ServiceRegistry.lookupProviders(IdentityProvider.class);
@@ -186,7 +194,8 @@ public class SocialResource {
}
if (provider == null) {
- return redirectToLogin(application, "invalid_provider");
+ log.warn("Failed to redirect to provider auth: " + providerId + " not found");
+ return redirectToLogin(application, IdentityProviderErrors.INVALID_PROVIDER);
}
IdentityProviderCallback callback = new IdentityProviderCallback();
@@ -195,12 +204,13 @@ public class SocialResource {
callback.setUriInfo(uriInfo);
callback.setProviderKey(null); // TODO Get provider key
callback.setProviderSecret(null); // TODO Get provider secret
+ callback.setProviderState(getProviderState(provider));
- URI authUrl = provider.getAuthUrl(callback);
- if (authUrl != null) {
- return Response.seeOther(authUrl).build();
- } else {
- return redirectToLogin(application, "invalid_provider");
+ try {
+ return Response.seeOther(provider.getAuthUrl(callback)).build();
+ } catch (Throwable t) {
+ log.warn("Failed to redirect to provider auth", t);
+ return redirectToLogin(application, IdentityProviderErrors.PROVIDER_ERROR);
}
}
diff --git a/social/src/main/java/org/keycloak/social/twitter/TwitterProvider.java b/social/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
index 3a28e14b4f..58ea524bf4 100644
--- a/social/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
+++ b/social/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
@@ -23,9 +23,9 @@ package org.keycloak.social.twitter;
import java.net.URI;
-import org.jboss.resteasy.logging.Logger;
import org.keycloak.social.IdentityProvider;
import org.keycloak.social.IdentityProviderCallback;
+import org.keycloak.social.IdentityProviderException;
import org.picketlink.idm.model.SimpleUser;
import org.picketlink.idm.model.User;
@@ -38,15 +38,13 @@ import twitter4j.auth.RequestToken;
*/
public class TwitterProvider implements IdentityProvider {
- private static final Logger log = Logger.getLogger(TwitterProvider.class);
-
@Override
public String getId() {
return "twitter";
}
@Override
- public URI getAuthUrl(IdentityProviderCallback callback) {
+ public URI getAuthUrl(IdentityProviderCallback callback) throws IdentityProviderException {
try {
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(callback.getProviderKey(), callback.getProviderSecret());
@@ -55,8 +53,7 @@ public class TwitterProvider implements IdentityProvider {
callback.putState(requestToken.getToken(), requestToken);
return callback.createUri(requestToken.getAuthenticationURL()).build();
} catch (Exception e) {
- log.error("Failed to retrieve login url", e);
- return null;
+ throw new IdentityProviderException(e);
}
}
@@ -71,7 +68,7 @@ public class TwitterProvider implements IdentityProvider {
}
@Override
- public User processCallback(IdentityProviderCallback callback) {
+ public User processCallback(IdentityProviderCallback callback) throws IdentityProviderException {
try {
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(callback.getProviderKey(), callback.getProviderSecret());
@@ -86,8 +83,7 @@ public class TwitterProvider implements IdentityProvider {
user.setFirstName(twitterUser.getName());
return user;
} catch (Exception e) {
- log.error("Failed to process callback", e);
- return null;
+ throw new IdentityProviderException(e);
}
}
diff --git a/social/src/main/resources/META-INF/services/org.eventjuggler.services.idb.provider.IdentityProvider b/social/src/main/resources/META-INF/services/org.keycloak.social.IdentityProvider
similarity index 100%
rename from social/src/main/resources/META-INF/services/org.eventjuggler.services.idb.provider.IdentityProvider
rename to social/src/main/resources/META-INF/services/org.keycloak.social.IdentityProvider