keycloak-memoizeit

Details

diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index 980487c..cd46424 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -49,7 +49,11 @@ public class KeycloakApplication extends Application {
         KeycloakSessionFactory f = createSessionFactory();
         this.factory = f;
         classes.add(KeycloakSessionCleanupFilter.class);
-        singletons.add(new RealmsResource(new TokenManager(), new SocialRequestManager()));
+
+        TokenManager tokenManager = new TokenManager();
+
+        singletons.add(new RealmsResource(tokenManager));
+        singletons.add(new SocialResource(tokenManager, new SocialRequestManager()));
         classes.add(SkeletonKeyContextResolver.class);
         classes.add(SaasService.class);
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
index 4375025..9f626a4 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -43,11 +43,8 @@ public class RealmsResource {
 
     protected TokenManager tokenManager;
 
-    protected SocialRequestManager socialRequestManager;
-
-    public RealmsResource(TokenManager tokenManager, SocialRequestManager socialRequestManager) {
+    public RealmsResource(TokenManager tokenManager) {
         this.tokenManager = tokenManager;
-        this.socialRequestManager = socialRequestManager;
     }
 
     public static UriBuilder realmBaseUrl(UriInfo uriInfo) {
@@ -73,24 +70,6 @@ public class RealmsResource {
 
     }
 
-    @Path("{realm}/social")
-    public SocialService getSocialService(final @PathParam("realm") String id) {
-        return new Transaction(false) {
-            @Override
-            protected SocialService callImpl() {
-                RealmManager realmManager = new RealmManager(session);
-                RealmModel realm = realmManager.getRealm(id);
-                if (realm == null) {
-                    logger.debug("realm not found");
-                    throw new NotFoundException();
-                }
-                SocialService socialService = new SocialService(realm, tokenManager, socialRequestManager);
-                resourceContext.initResource(socialService);
-                return socialService;
-            }
-        }.call();
-    }
-
     @Path("{realm}")
     public PublicRealmResource getRealmResource(final @PathParam("realm") String id) {
         return new Transaction(false) {
diff --git a/services/src/main/java/org/keycloak/services/resources/SaasService.java b/services/src/main/java/org/keycloak/services/resources/SaasService.java
index 3665c53..7b5cb43 100755
--- a/services/src/main/java/org/keycloak/services/resources/SaasService.java
+++ b/services/src/main/java/org/keycloak/services/resources/SaasService.java
@@ -222,7 +222,7 @@ public class SaasService {
         URI register = contextRoot(uriInfo).path(saasRegisterPath).build();
         request.setAttribute("KEYCLOAK_LOGIN_ACTION", action);
         request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", register);
-        request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", SocialService.redirectToProviderAuthUrl(uriInfo).build(realm.getId()));
+        request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", SocialResource.redirectToProviderAuthUrl(uriInfo).build(realm.getId()));
         request.forward(loginFormPath);
     }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 4f295fe..8d749a0 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -6,6 +6,8 @@ import org.jboss.resteasy.jose.jws.JWSInput;
 import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
 import org.jboss.resteasy.jwt.JsonSerialization;
 import org.jboss.resteasy.logging.Logger;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.jboss.resteasy.spi.HttpResponse;
 import org.keycloak.representations.AccessTokenResponse;
 import org.keycloak.representations.SkeletonKeyToken;
 import org.keycloak.services.managers.AccessCodeEntry;
@@ -25,6 +27,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
@@ -40,20 +43,32 @@ import java.util.Map;
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public class TokenService extends AbstractLoginService {
-
+public class TokenService {
 
     protected static final Logger logger = Logger.getLogger(TokenService.class);
 
+    protected RealmModel realm;
+    protected TokenManager tokenManager;
+    protected AuthenticationManager authManager = new AuthenticationManager();
+
     @Context
     protected Providers providers;
     @Context
     protected SecurityContext securityContext;
+    @Context
+    protected UriInfo uriInfo;
+    @Context
+    protected HttpHeaders headers;
+    @Context
+    HttpRequest request;
+    @Context
+    HttpResponse response;
 
     private ResourceAdminManager resourceAdminManager = new ResourceAdminManager();
 
     public TokenService(RealmModel realm, TokenManager tokenManager) {
-        super(realm, tokenManager);
+        this.realm = realm;
+        this.tokenManager = tokenManager;
     }
 
     public static UriBuilder tokenServiceBaseUrl(UriInfo uriInfo) {
@@ -168,16 +183,16 @@ public class TokenService extends AbstractLoginService {
                 String redirect = formData.getFirst("redirect_uri");
 
                 if (!realm.isEnabled()) {
-                    securityFailureForward("Realm not enabled.");
+                    OAuthUtil.securityFailureForward(request, "Realm not enabled.");
                     return null;
                 }
                 UserModel client = realm.getUser(clientId);
                 if (client == null) {
-                    securityFailureForward("Unknown login requester.");
+                    OAuthUtil.securityFailureForward(request, "Unknown login requester.");
                     return null;
                 }
                 if (!client.isEnabled()) {
-                    securityFailureForward("Login requester not enabled.");
+                    OAuthUtil.securityFailureForward(request, "Login requester not enabled.");
                     return null;
                 }
                 String username = formData.getFirst("username");
@@ -185,11 +200,11 @@ public class TokenService extends AbstractLoginService {
                 if (user == null) {
                     logger.error("Incorrect user name.");
                     request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Incorrect user name.");
-                    forwardToLoginForm(redirect, clientId, scopeParam, state);
+                    OAuthUtil.forwardToLoginForm(realm, request, uriInfo, redirect, clientId, scopeParam, state);
                     return null;
                 }
                 if (!user.isEnabled()) {
-                    securityFailureForward("Your account is not enabled.");
+                    OAuthUtil.securityFailureForward(request, "Your account is not enabled.");
                     return null;
                 }
                 boolean authenticated = authManager.authenticateForm(realm, user, formData);
@@ -197,11 +212,12 @@ public class TokenService extends AbstractLoginService {
                     logger.error("Authentication failed");
                     request.setAttribute("username", username);
                     request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid credentials.");
-                    forwardToLoginForm(redirect, clientId, scopeParam, state);
+                    OAuthUtil.forwardToLoginForm(realm, request, uriInfo, redirect, clientId, scopeParam, state);
                     return null;
                 }
 
-                return processAccessCode(scopeParam, state, redirect, client, user);
+                return OAuthUtil.processAccessCode(realm, tokenManager, authManager, request, uriInfo, scopeParam, state,
+                        redirect, client, user);
             }
         }.call();
     }
@@ -341,18 +357,18 @@ public class TokenService extends AbstractLoginService {
         return new Transaction() {
             protected Response callImpl() {
                 if (!realm.isEnabled()) {
-                    securityFailureForward("Realm not enabled");
+                    OAuthUtil.securityFailureForward(request, "Realm not enabled");
                     return null;
                 }
                 UserModel client = realm.getUser(clientId);
                 if (client == null) {
-                    securityFailureForward("Unknown login requester.");
+                    OAuthUtil.securityFailureForward(request, "Unknown login requester.");
                     transaction.rollback();
                     return null;
                 }
 
                 if (!client.isEnabled()) {
-                    securityFailureForward("Login requester not enabled.");
+                    OAuthUtil.securityFailureForward(request, "Login requester not enabled.");
                     transaction.rollback();
                     session.close();
                     return null;
@@ -362,7 +378,7 @@ public class TokenService extends AbstractLoginService {
                 RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
                 boolean isResource = realm.hasRole(client, resourceRole);
                 if (!isResource && !realm.hasRole(client, identityRequestRole)) {
-                    securityFailureForward("Login requester not allowed to request login.");
+                    OAuthUtil.securityFailureForward(request, "Login requester not allowed to request login.");
                     transaction.rollback();
                     session.close();
                     return null;
@@ -371,10 +387,11 @@ public class TokenService extends AbstractLoginService {
                 UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
                 if (user != null) {
                     logger.info(user.getLoginName() + " already logged in.");
-                    return processAccessCode(scopeParam, state, redirect, client, user);
+                    return OAuthUtil.processAccessCode(realm, tokenManager, authManager, request, uriInfo, scopeParam, state,
+                            redirect, client, user);
                 }
 
-                forwardToLoginForm(redirect, clientId, scopeParam, state);
+                OAuthUtil.forwardToLoginForm(realm, request, uriInfo, redirect, clientId, scopeParam, state);
                 return null;
             }
         }.call();
@@ -415,14 +432,14 @@ public class TokenService extends AbstractLoginService {
                     logger.debug("Failed to verify signature", ignored);
                 }
                 if (!verifiedCode) {
-                    securityFailureForward("Illegal access code.");
+                    OAuthUtil.securityFailureForward(request, "Illegal access code.");
                     session.close();
                     return null;
                 }
                 String key = input.readContent(String.class);
                 AccessCodeEntry accessCodeEntry = tokenManager.getAccessCode(key);
                 if (accessCodeEntry == null) {
-                    securityFailureForward("Unknown access code.");
+                    OAuthUtil.securityFailureForward(request, "Unknown access code.");
                     session.close();
                     return null;
                 }
@@ -434,7 +451,7 @@ public class TokenService extends AbstractLoginService {
                     return redirectAccessDenied(redirect, state);
                 }
 
-                return redirectAccessCode(accessCodeEntry, state, redirect);
+                return OAuthUtil.redirectAccessCode(realm, authManager, uriInfo, accessCodeEntry, state, redirect);
             }
         }.call();
     }
@@ -446,9 +463,4 @@ public class TokenService extends AbstractLoginService {
         return location.build();
     }
 
-    @Override
-    protected Logger getLogger() {
-        return logger;
-    }
-
 }
diff --git a/social/core/src/main/java/org/keycloak/social/SocialProvider.java b/social/core/src/main/java/org/keycloak/social/SocialProvider.java
index 81d9216..70da76d 100644
--- a/social/core/src/main/java/org/keycloak/social/SocialProvider.java
+++ b/social/core/src/main/java/org/keycloak/social/SocialProvider.java
@@ -21,25 +21,20 @@
  */
 package org.keycloak.social;
 
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlTransient;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
-@XmlRootElement
 public interface SocialProvider {
 
     String getId();
 
-    @XmlTransient
     AuthRequest getAuthUrl(SocialProviderConfig config) throws SocialProviderException;
 
     String getRequestIdParamName();
 
     String getName();
 
-    @XmlTransient
     SocialUser processCallback(SocialProviderConfig config, AuthCallback callback) throws SocialProviderException;
 
 }

social/README.md 17(+12 -5)

diff --git a/social/README.md b/social/README.md
index 08f4dc1..90df3c2 100644
--- a/social/README.md
+++ b/social/README.md
@@ -18,7 +18,17 @@ Social provides implementations for Facebook, Google and Twitter.
 Configure Facebook
 ------------------
 
+Open https://developers.facebook.com/apps. Click on Create New App
 
+Use any app name that you'd like, click Continue
+
+Select Disabled for Sandbox Mode
+
+Under Select how your app integrates with Facebook select Website with Facebook login. Fill in the form with the following values:
+
+* Site URL: http://<HOSTNAME>[<PORT>]/auth-server/rest/social/callback
+
+Click on Save changes. Use the value of App ID as the value of the system property "keycloak.social.facebook.key", and the value of App Secret as the value of "keycloak.social.facebook.secret".
 
 
 Configure Google
@@ -30,7 +40,7 @@ Use any name that you'd like, click Create Project, select API Access and click 
 
 Use any product name you'd like and leave the other fields empty, then click Next. On the next page select Web application as the application type. Click more options next> to Your site or hostname. Fill in the form with the following values:
 
-* Authorized Redirect URIs: http://<HOSTNAME>[<PORT>]/auth-server/rest/realms/<REALM>/social/callback
+* Authorized Redirect URIs: http://<HOSTNAME>[<PORT>]/auth-server/rest/social/callback
 
 Click on Create client ID. Use the value of Client ID as the value of the system property "keycloak.social.google.key", and the value of Client secret as the value of "keycloak.social.google.secret".
 
@@ -40,10 +50,7 @@ Configure Twitter
 
 Open https://dev.twitter.com/apps. Click on Create a new application.
 
-Fill in name, description and website. For Callback URL use the following value:
-
-Callback URL: http://mbaas-stianst.rhcloud.com/ejs-identity/api/callback/516131bc-e3e4-4736-928b-cf1df8c0fe74
-Note: Twitter doesn't allow localhost as domain, use 127.0.0.1 instead!
+Fill in name, description and website. Leave Callback URL empty!
 
 Agree to the rules, fill in the captcha and click on Create your Twitter application.
 
diff --git a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
index ee5175b..d014e81 100644
--- a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
+++ b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
@@ -49,7 +49,7 @@ public class TwitterProvider implements SocialProvider {
             Twitter twitter = new TwitterFactory().getInstance();
             twitter.setOAuthConsumer(request.getKey(), request.getSecret());
 
-            RequestToken requestToken = twitter.getOAuthRequestToken();
+            RequestToken requestToken = twitter.getOAuthRequestToken(request.getCallbackUrl());
 
             return AuthRequestBuilder.create(requestToken.getToken(), requestToken.getAuthenticationURL())
                     .setAttribute("token", requestToken.getToken()).setAttribute("tokenSecret", requestToken.getTokenSecret())