keycloak-memoizeit

Changes

examples/as7-eap-demo/server/src/main/webapp/saas/saas-register.jsp 88(+0 -88)

forms/pom.xml 4(+2 -2)

pom.xml 2(+1 -1)

Details

diff --git a/examples/as7-eap-demo/server/pom.xml b/examples/as7-eap-demo/server/pom.xml
index 5cfb75b..a0b7c26 100755
--- a/examples/as7-eap-demo/server/pom.xml
+++ b/examples/as7-eap-demo/server/pom.xml
@@ -52,7 +52,7 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-sdk-html</artifactId>
+            <artifactId>keycloak-forms</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/menu.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/menu.html
index e10cd0c..21c4733 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/menu.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/menu.html
@@ -12,8 +12,8 @@
                         <!-- <select class="nav pull-left" ng-options="r.name for r in current.realms"></select> -->
                     </div>
                     <ul class="nav pull-right" data-ng-hide="auth.loggedIn">
-                        <li><a href="/auth-server/rest/saas/loginPage.html">Login</a></li>
-                        <li><a href="/auth-server/saas/saas-register.jsp">Register</a></li>
+                        <li><a href="/auth-server/rest/saas/login">Login</a></li>
+                        <li><a href="/auth-server/rest/saas/registrations">Register</a></li>
                     </ul>
                     <ul class="nav pull-right" data-ng-show="auth.loggedIn">
                         <li class="divider-vertical-left dropdown"><a data-toggle="dropdown" class="dropdown-toggle" href="#"><i

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index b55e06d..b0e3b22 100755
--- a/pom.xml
+++ b/pom.xml
@@ -58,7 +58,7 @@
         <module>integration</module>
         <module>examples</module>
         <module>social</module>
-        <module>sdk-html</module>
+        <module>forms</module>
         <!--<module>ui</module> -->
     </modules>
 
diff --git a/services/src/main/java/org/keycloak/services/resources/OAuthUtil.java b/services/src/main/java/org/keycloak/services/resources/OAuthUtil.java
index 857c0ce..e834965 100644
--- a/services/src/main/java/org/keycloak/services/resources/OAuthUtil.java
+++ b/services/src/main/java/org/keycloak/services/resources/OAuthUtil.java
@@ -1,7 +1,5 @@
 package org.keycloak.services.resources;
 
-import java.net.URI;
-
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
@@ -22,7 +20,6 @@ public class OAuthUtil {
     private static final Logger log = Logger.getLogger(OAuthUtil.class);
 
     public final static String securityFailurePath = "/saas/securityFailure.jsp";
-    public final static String loginFormPath = "/sdk/login.xhtml";
     public final static String oauthFormPath = "/saas/oauthGrantForm.jsp";
 
     public static Response processAccessCode(RealmModel realm, TokenManager tokenManager, AuthenticationManager authManager,
@@ -75,16 +72,22 @@ public class OAuthUtil {
     public static void forwardToLoginForm(RealmModel realm, HttpRequest request, UriInfo uriInfo, String redirect,
             String clientId, String scopeParam, String state) {
         request.setAttribute(RealmModel.class.getName(), realm);
-        request.setAttribute("KEYCLOAK_LOGIN_ACTION", TokenService.processLoginUrl(uriInfo).build(realm.getId()));
-        request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", SocialResource.redirectToProviderAuthUrl(uriInfo).build(realm.getId()));
-        request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", URI.create("not-implemented-yet"));
+
+        request.setAttribute("KEYCLOAK_LOGIN_PAGE", Urls.realmLoginPage(uriInfo, realm.getId()));
+        request.setAttribute("KEYCLOAK_LOGIN_ACTION", Urls.realmLoginAction(uriInfo, realm.getId()));
+
+        request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", Urls.realmRegisterPage(uriInfo, realm.getId()));
+        request.setAttribute("KEYCLOAK_REGISTRATION_ACTION", Urls.realmRegisterAction(uriInfo, realm.getId()));
+
+        request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", Urls.socialRedirectToProviderAuth(uriInfo, realm.getId()));
 
         // RESTEASY eats the form data, so we send via an attribute
         request.setAttribute("redirect_uri", redirect);
         request.setAttribute("client_id", clientId);
         request.setAttribute("scope", scopeParam);
         request.setAttribute("state", state);
-        request.forward(loginFormPath);
+
+        request.forward(Pages.loginForm);
     }
 
     public static void oauthGrantPage(RealmModel realm, HttpRequest request, UriInfo uriInfo, AccessCodeEntry accessCode,
diff --git a/services/src/main/java/org/keycloak/services/resources/Pages.java b/services/src/main/java/org/keycloak/services/resources/Pages.java
new file mode 100644
index 0000000..ae56297
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/Pages.java
@@ -0,0 +1,8 @@
+package org.keycloak.services.resources;
+
+public class Pages {
+
+    public final static String loginForm = "/sdk/login.xhtml";
+    public final static String registerForm = "/sdk/register.xhtml";
+
+}
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 7b5cb43..af8b1aa 100755
--- a/services/src/main/java/org/keycloak/services/resources/SaasService.java
+++ b/services/src/main/java/org/keycloak/services/resources/SaasService.java
@@ -39,8 +39,6 @@ public class SaasService {
     @Context
     HttpResponse response;
 
-    protected String saasLoginPath = "/saas/saas-login.jsp";
-    protected String saasRegisterPath = "/saas/saas-register.jsp";
     protected String adminPath = "/saas/admin/index.html";
     protected AuthenticationManager authManager = new AuthenticationManager();
 
@@ -170,7 +168,7 @@ public class SaasService {
         }.call();
     }
 
-    @Path("loginPage.html")
+    @Path("login")
     @GET
     @NoCache
     public void loginPage() {
@@ -180,7 +178,22 @@ public class SaasService {
                 RealmManager realmManager = new RealmManager(session);
                 RealmModel realm = realmManager.defaultRealm();
                 authManager.expireSaasIdentityCookie(uriInfo);
-                forwardToLoginForm(realm);
+                forwardToLoginForm(realm, null, null);
+            }
+        }.run();
+    }
+
+    @Path("registrations")
+    @GET
+    @NoCache
+    public void registerPage() {
+        new Transaction() {
+            @Override
+            protected void runImpl() {
+                RealmManager realmManager = new RealmManager(session);
+                RealmModel realm = realmManager.defaultRealm();
+                authManager.expireSaasIdentityCookie(uriInfo);
+                forwardToRegisterForm(realm, null, null);
             }
         }.run();
     }
@@ -195,7 +208,7 @@ public class SaasService {
                 RealmManager realmManager = new RealmManager(session);
                 RealmModel realm = realmManager.defaultRealm();
                 authManager.expireSaasIdentityCookie(uriInfo);
-                forwardToLoginForm(realm);
+                forwardToLoginForm(realm, null, null);
             }
         }.run();
     }
@@ -214,16 +227,42 @@ public class SaasService {
         }.run();
     }
 
-    public final static String loginFormPath = "/sdk/login.xhtml";
+    protected void forwardToLoginForm(RealmModel realm, String error, MultivaluedMap<String, String> formData) {
+        if (error != null) {
+            request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", error);
+        }
+
+        if (formData != null) {
+            request.setAttribute("KEYCLOAK_FORM_DATA", formData);
+        }
+
+        forwardToForm(realm, Pages.loginForm);
+    }
+
+    protected void forwardToRegisterForm(RealmModel realm, String error, MultivaluedMap<String, String> formData) {
+        if (error != null) {
+            request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", error);
+        }
+
+        if (formData != null) {
+            request.setAttribute("KEYCLOAK_FORM_DATA", formData);
+        }
+
+        forwardToForm(realm, Pages.registerForm);
+    }
 
-    protected void forwardToLoginForm(RealmModel realm) {
+    protected void forwardToForm(RealmModel realm, String form) {
         request.setAttribute(RealmModel.class.getName(), realm);
-        URI action = uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "processLogin").build();
-        URI register = contextRoot(uriInfo).path(saasRegisterPath).build();
-        request.setAttribute("KEYCLOAK_LOGIN_ACTION", action);
-        request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", register);
-        request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", SocialResource.redirectToProviderAuthUrl(uriInfo).build(realm.getId()));
-        request.forward(loginFormPath);
+
+        request.setAttribute("KEYCLOAK_LOGIN_PAGE", Urls.saasLoginPage(uriInfo));
+        request.setAttribute("KEYCLOAK_LOGIN_ACTION", Urls.saasLoginAction(uriInfo));
+
+        request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", Urls.saasRegisterPage(uriInfo));
+        request.setAttribute("KEYCLOAK_REGISTRATION_ACTION", Urls.saasRegisterAction(uriInfo));
+
+        request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", Urls.socialRedirectToProviderAuth(uriInfo, realm.getId()));
+
+        request.forward(form);
     }
 
 
@@ -246,22 +285,19 @@ public class SaasService {
                 UserModel user = realm.getUser(username);
                 if (user == null) {
                     logger.info("Not Authenticated! Incorrect user name");
-                    request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Incorrect user name.");
-                    forwardToLoginForm(realm);
+                    forwardToLoginForm(realm, "Invalid username or password", formData);
                     return null;
                 }
                 if (!user.isEnabled()) {
                     logger.info("NAccount is disabled, contact admin.");
-                    request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Account is disabled, contact admin.");
-                    forwardToLoginForm(realm);
+                    forwardToLoginForm(realm, "Account is disabled, contact admin.", formData);
                     return null;
                 }
 
                 boolean authenticated = authManager.authenticateForm(realm, user, formData);
                 if (!authenticated) {
                     logger.info("Not Authenticated! Invalid credentials");
-                    request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid credentials.");
-                    forwardToLoginForm(realm);
+                    forwardToLoginForm(realm, "Invalid username or password", formData);
                     return null;
                 }
 
@@ -295,24 +331,24 @@ public class SaasService {
     @Path("registrations")
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response processRegister(final @FormParam("name") String fullname,
-                                    final @FormParam("email") String email,
-                                    final @FormParam("username") String username,
-                                    final @FormParam("password") String password,
-                                    final @FormParam("password-confirm") String confirm) {
-        if (!password.equals(confirm)) {
-            request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Password confirmation doesn't match.");
-            request.forward(saasRegisterPath);
-            return null;
-        }
+    public Response processRegister(final MultivaluedMap<String, String> formData) {
         return new Transaction() {
             @Override
             protected Response callImpl() {
                 RealmManager realmManager = new RealmManager(session);
                 RealmModel defaultRealm = realmManager.defaultRealm();
+
+                String error = validateRegistrationForm(formData);
+                if (error != null) {
+                    forwardToRegisterForm(defaultRealm, error, formData);
+                    return null;
+                }
+
                 UserRepresentation newUser = new UserRepresentation();
-                newUser.setUsername(username);
-                newUser.setEmail(email);
+                newUser.setUsername(formData.getFirst("username"));
+                newUser.setEmail(formData.getFirst("email"));
+
+                String fullname = formData.getFirst("name");
                 if (fullname != null) {
                     StringTokenizer tokenizer = new StringTokenizer(fullname, " ");
                     StringBuffer first = null;
@@ -334,11 +370,11 @@ public class SaasService {
                     newUser.setFirstName(first.toString());
                     newUser.setLastName(last);
                 }
-                newUser.credential(CredentialRepresentation.PASSWORD, password);
+                newUser.credential(CredentialRepresentation.PASSWORD, formData.getFirst("password"));
                 UserModel user = registerMe(defaultRealm, newUser);
                 if (user == null) {
                     request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Username already exists.");
-                    request.forward(saasRegisterPath);
+                    forwardToRegisterForm(defaultRealm, "Username already exists.", formData);
                     return null;
 
                 }
@@ -376,5 +412,32 @@ public class SaasService {
         return user;
     }
 
+    private String validateRegistrationForm(MultivaluedMap<String, String> formData) {
+        if (isEmpty(formData.getFirst("name"))) {
+            return "Please specify full name";
+        }
+
+        if (isEmpty(formData.getFirst("email"))) {
+            return "Please specify email";
+        }
+
+        if (isEmpty(formData.getFirst("username"))) {
+            return "Please specify username";
+        }
+
+        if (isEmpty(formData.getFirst("password"))) {
+            return "Please specify password";
+        }
+
+        if (!formData.getFirst("password").equals(formData.getFirst("password-confirm"))) {
+            return "Password confirmation doesn't match.";
+        }
+
+        return null;
+    }
+
+    private boolean isEmpty(String s) {
+        return s == null || s.length() == 0;
+    }
 
 }
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 8d749a0..a9b1e8f 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -199,7 +199,8 @@ public class TokenService {
                 UserModel user = realm.getUser(username);
                 if (user == null) {
                     logger.error("Incorrect user name.");
-                    request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Incorrect user name.");
+                    request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid username or password");
+                    request.setAttribute("KEYCLOAK_FORM_DATA", formData);
                     OAuthUtil.forwardToLoginForm(realm, request, uriInfo, redirect, clientId, scopeParam, state);
                     return null;
                 }
@@ -211,7 +212,8 @@ public class TokenService {
                 if (!authenticated) {
                     logger.error("Authentication failed");
                     request.setAttribute("username", username);
-                    request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid credentials.");
+                    request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid username or password");
+                    request.setAttribute("KEYCLOAK_FORM_DATA", formData);
                     OAuthUtil.forwardToLoginForm(realm, request, uriInfo, redirect, clientId, scopeParam, state);
                     return null;
                 }
diff --git a/services/src/main/java/org/keycloak/services/resources/Urls.java b/services/src/main/java/org/keycloak/services/resources/Urls.java
new file mode 100644
index 0000000..7e2b2e8
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/Urls.java
@@ -0,0 +1,45 @@
+package org.keycloak.services.resources;
+
+import java.net.URI;
+
+import javax.ws.rs.core.UriInfo;
+
+public class Urls {
+
+    public static URI realmLoginAction(UriInfo uriInfo, String realmId) {
+        return TokenService.processLoginUrl(uriInfo).build(realmId);
+    }
+
+    public static URI realmLoginPage(UriInfo uriInfo, String realmId) {
+        return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "processLogin").build();
+    }
+
+    public static URI realmRegisterAction(UriInfo uriInfo, String realmId) {
+        return URI.create("not-implemented-yet");
+    }
+
+    public static URI realmRegisterPage(UriInfo uriInfo, String realmId) {
+        return URI.create("not-implemented-yet");
+    }
+
+    public static URI saasLoginAction(UriInfo uriInfo) {
+        return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "processLogin").build();
+    }
+
+    public static URI saasLoginPage(UriInfo uriInfo) {
+        return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "loginPage").build();
+    }
+
+    public static URI saasRegisterAction(UriInfo uriInfo) {
+        return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "processRegister").build();
+    }
+
+    public static URI saasRegisterPage(UriInfo uriInfo) {
+        return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "registerPage").build();
+    }
+
+    public static URI socialRedirectToProviderAuth(UriInfo uriInfo, String realmId) {
+        return SocialResource.redirectToProviderAuthUrl(uriInfo).build(realmId);
+    }
+
+}