diff --git a/core/pom.xml b/core/pom.xml index 56f2396f4f..760584f736 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,15 +29,10 @@ provided - javax.servlet - servlet-api + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec provided - - org.jboss.resteasy - tjws - test - junit junit diff --git a/examples/as7-eap-demo/customer-app/pom.xml b/examples/as7-eap-demo/customer-app/pom.xml index bdd517d293..fb580bf344 100755 --- a/examples/as7-eap-demo/customer-app/pom.xml +++ b/examples/as7-eap-demo/customer-app/pom.xml @@ -23,9 +23,9 @@ - - javax.servlet - servlet-api + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec provided diff --git a/examples/as7-eap-demo/product-app/pom.xml b/examples/as7-eap-demo/product-app/pom.xml index 92563e77b1..7172325095 100755 --- a/examples/as7-eap-demo/product-app/pom.xml +++ b/examples/as7-eap-demo/product-app/pom.xml @@ -24,8 +24,8 @@ - javax.servlet - servlet-api + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec provided diff --git a/examples/as7-eap-demo/server/src/main/java/org/keycloak/example/demo/DemoApplication.java b/examples/as7-eap-demo/server/src/main/java/org/keycloak/example/demo/DemoApplication.java index 29045058d7..b7c11f217b 100755 --- a/examples/as7-eap-demo/server/src/main/java/org/keycloak/example/demo/DemoApplication.java +++ b/examples/as7-eap-demo/server/src/main/java/org/keycloak/example/demo/DemoApplication.java @@ -11,6 +11,8 @@ import org.keycloak.services.resources.KeycloakApplication; import org.keycloak.services.resources.SaasService; import org.keycloak.services.resources.SaasService; +import javax.servlet.ServletContext; +import javax.ws.rs.core.Context; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -20,8 +22,8 @@ import java.io.InputStream; */ public class DemoApplication extends KeycloakApplication { - public DemoApplication() { - super(); + public DemoApplication(@Context ServletContext servletContext) { + super(servletContext); KeycloakSession session = factory.createSession(); session.getTransaction().begin(); RealmManager realmManager = new RealmManager(session); diff --git a/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/web.xml b/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/web.xml index 4c6404bb9c..6829b0e56e 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/web.xml +++ b/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/web.xml @@ -21,6 +21,16 @@ true + + Keycloak Session Management + org.keycloak.services.filters.KeycloakSessionServletFilter + + + + Keycloak Session Management + /rest/* + + Resteasy /rest/* diff --git a/integration/as7-eap6/adapter/pom.xml b/integration/as7-eap6/adapter/pom.xml index 69c4ff1188..11e11e95b2 100755 --- a/integration/as7-eap6/adapter/pom.xml +++ b/integration/as7-eap6/adapter/pom.xml @@ -33,7 +33,6 @@ org.jboss.spec.javax.servlet jboss-servlet-api_3.0_spec - 1.0.0.Final provided diff --git a/pom.xml b/pom.xml index 39e3315af1..e0c89cfdd6 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,8 @@ pom - 3.0.2.Final + 3.0.4.Final + 1.0.0.Beta12 2.5.0.Beta6 @@ -108,7 +109,21 @@ org.jboss.resteasy tjws ${resteasy.version} - provided + + + org.jboss.resteasy + resteasy-undertow + ${resteasy.version} + + + io.undertow + undertow-servlet + ${undertow.version} + + + io.undertow + undertow-core + ${undertow.version} org.codehaus.jackson @@ -131,9 +146,9 @@ 1.9.12 - javax.servlet - servlet-api - 2.5 + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec + 1.0.1.Final org.jboss.resteasy diff --git a/services/pom.xml b/services/pom.xml index 74452e2074..02f2c8ae9a 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -79,12 +79,7 @@ - - org.jboss.resteasy - tjws - test - - + org.jboss.resteasy jaxrs-api provided @@ -105,13 +100,18 @@ provided - javax.servlet - servlet-api + org.jboss.resteasy + resteasy-undertow test - org.jboss.resteasy - tjws + io.undertow + undertow-servlet + test + + + io.undertow + undertow-core test @@ -124,6 +124,11 @@ jackson-mapper-asl provided + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec + provided + org.codehaus.jackson jackson-xc diff --git a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionCreateFilter.java b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionCreateFilter.java index 870aec9772..cc0eb284e4 100755 --- a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionCreateFilter.java +++ b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionCreateFilter.java @@ -7,8 +7,6 @@ import org.keycloak.services.models.KeycloakSessionFactory; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; -import javax.ws.rs.container.ContainerResponseContext; -import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.container.PreMatching; import java.io.IOException; diff --git a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java new file mode 100755 index 0000000000..6506300a21 --- /dev/null +++ b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java @@ -0,0 +1,56 @@ +package org.keycloak.services.filters; + +import org.jboss.resteasy.spi.ResteasyProviderFactory; +import org.keycloak.services.models.KeycloakSession; +import org.keycloak.services.models.KeycloakSessionFactory; +import org.keycloak.services.models.KeycloakTransaction; + +import javax.servlet.*; +import java.io.IOException; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class KeycloakSessionServletFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + KeycloakSessionFactory factory = (KeycloakSessionFactory)servletRequest.getServletContext().getAttribute(KeycloakSessionFactory.class.getName()); + if (factory == null) throw new ServletException("Factory was null"); + KeycloakSession session = factory.createSession(); + ResteasyProviderFactory.pushContext(KeycloakSession.class, session); + KeycloakTransaction tx = session.getTransaction(); + ResteasyProviderFactory.pushContext(KeycloakTransaction.class, tx); + tx.begin(); + try { + filterChain.doFilter(servletRequest, servletResponse); + if (tx.isActive()) { + if (tx.getRollbackOnly()) tx.rollback(); + else tx.commit(); + } + } catch (IOException ex) { + if (tx.isActive()) tx.rollback(); + throw ex; + } catch (ServletException ex) { + if (tx.isActive()) tx.rollback(); + throw ex; + } + catch (RuntimeException ex) { + if (tx.isActive()) tx.rollback(); + throw ex; + } finally { + session.close(); + ResteasyProviderFactory.clearContextData(); + } + + } + + @Override + public void destroy() { + } +} diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java index 728df77484..aef5b36d16 100755 --- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java +++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java @@ -16,11 +16,7 @@ import org.keycloak.services.resources.RealmsResource; import org.keycloak.services.resources.SaasService; import javax.ws.rs.NotAuthorizedException; -import javax.ws.rs.core.Cookie; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.NewCookie; -import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.*; import java.net.URI; import java.util.HashSet; import java.util.List; diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java index afd24063df..997ab2c3f8 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -7,7 +7,10 @@ import org.keycloak.services.models.*; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicLong; /** diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java index fb1d342f81..fd06088b6a 100755 --- a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java +++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java @@ -5,8 +5,8 @@ import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.logging.Logger; import org.keycloak.TokenIdGenerator; import org.keycloak.representations.idm.admin.LogoutAction; -import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.ApplicationModel; +import org.keycloak.services.models.RealmModel; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Form; diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceManager.java index 85c2a7a42a..5da6c8c06c 100755 --- a/services/src/main/java/org/keycloak/services/managers/ResourceManager.java +++ b/services/src/main/java/org/keycloak/services/managers/ResourceManager.java @@ -1,12 +1,7 @@ package org.keycloak.services.managers; import org.keycloak.representations.idm.*; -import org.keycloak.representations.idm.ApplicationRepresentation; -import org.keycloak.services.models.RealmModel; -import org.keycloak.services.models.ApplicationModel; -import org.keycloak.services.models.RoleModel; -import org.keycloak.services.models.UserCredentialModel; -import org.keycloak.services.models.UserModel; +import org.keycloak.services.models.*; /** * @author Bill Burke diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java index 9557cb76ae..c195e8306f 100755 --- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java +++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java @@ -5,8 +5,8 @@ import org.jboss.resteasy.jose.jws.JWSBuilder; import org.jboss.resteasy.jwt.JsonSerialization; import org.keycloak.representations.SkeletonKeyScope; import org.keycloak.representations.SkeletonKeyToken; -import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.ApplicationModel; +import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.RoleModel; import org.keycloak.services.models.UserModel; diff --git a/services/src/main/java/org/keycloak/services/models/jpa/entities/RealmEntity.java b/services/src/main/java/org/keycloak/services/models/jpa/entities/RealmEntity.java index bb55046c0c..a199f86409 100755 --- a/services/src/main/java/org/keycloak/services/models/jpa/entities/RealmEntity.java +++ b/services/src/main/java/org/keycloak/services/models/jpa/entities/RealmEntity.java @@ -1,13 +1,7 @@ package org.keycloak.services.models.jpa.entities; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.MapKey; -import javax.persistence.OneToMany; +import javax.persistence.*; import java.util.Collection; /** diff --git a/services/src/main/java/org/keycloak/services/models/jpa/entities/ResourceEntity.java b/services/src/main/java/org/keycloak/services/models/jpa/entities/ResourceEntity.java index 1dfca39e8d..fa3b3c2234 100755 --- a/services/src/main/java/org/keycloak/services/models/jpa/entities/ResourceEntity.java +++ b/services/src/main/java/org/keycloak/services/models/jpa/entities/ResourceEntity.java @@ -1,13 +1,6 @@ package org.keycloak.services.models.jpa.entities; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; +import javax.persistence.*; import java.util.Collection; /** diff --git a/services/src/main/java/org/keycloak/services/models/jpa/entities/UserRoleMappingEntity.java b/services/src/main/java/org/keycloak/services/models/jpa/entities/UserRoleMappingEntity.java index b7f2d111d2..ae68f9720c 100755 --- a/services/src/main/java/org/keycloak/services/models/jpa/entities/UserRoleMappingEntity.java +++ b/services/src/main/java/org/keycloak/services/models/jpa/entities/UserRoleMappingEntity.java @@ -4,7 +4,6 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; -import javax.persistence.OneToOne; /** * @author Bill Burke diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java b/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java index e12e54eab8..2b76984d3a 100755 --- a/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java +++ b/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java @@ -5,29 +5,16 @@ import org.jboss.resteasy.logging.Logger; import org.jboss.resteasy.security.PemUtils; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.services.managers.RealmManager; -import org.keycloak.services.models.KeycloakSession; -import org.keycloak.services.models.RealmModel; -import org.keycloak.services.models.RequiredCredentialModel; -import org.keycloak.services.models.ApplicationModel; -import org.keycloak.services.models.RoleModel; -import org.keycloak.services.models.UserCredentialModel; -import org.keycloak.services.models.UserModel; -import org.keycloak.services.models.picketlink.mappings.RealmData; +import org.keycloak.services.models.*; import org.keycloak.services.models.picketlink.mappings.ApplicationData; +import org.keycloak.services.models.picketlink.mappings.RealmData; import org.keycloak.services.models.picketlink.relationships.*; -import org.keycloak.services.models.picketlink.relationships.RequiredApplicationCredentialRelationship; import org.picketlink.idm.IdentityManager; import org.picketlink.idm.PartitionManager; import org.picketlink.idm.RelationshipManager; -import org.picketlink.idm.credential.Credentials; -import org.picketlink.idm.credential.Password; -import org.picketlink.idm.credential.TOTPCredential; -import org.picketlink.idm.credential.TOTPCredentials; -import org.picketlink.idm.credential.UsernamePasswordCredentials; -import org.picketlink.idm.credential.X509CertificateCredentials; +import org.picketlink.idm.credential.*; import org.picketlink.idm.model.AttributedType; import org.picketlink.idm.model.IdentityType; -import org.picketlink.idm.model.annotation.AttributeProperty; import org.picketlink.idm.model.sample.Grant; import org.picketlink.idm.model.sample.Role; import org.picketlink.idm.model.sample.SampleModel; @@ -40,13 +27,7 @@ import java.io.StringWriter; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * Meant to be a per-request object diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/UserAdapter.java b/services/src/main/java/org/keycloak/services/models/picketlink/UserAdapter.java index be85c88d30..6fc083512c 100755 --- a/services/src/main/java/org/keycloak/services/models/picketlink/UserAdapter.java +++ b/services/src/main/java/org/keycloak/services/models/picketlink/UserAdapter.java @@ -3,7 +3,6 @@ package org.keycloak.services.models.picketlink; import org.keycloak.services.models.UserModel; import org.picketlink.idm.IdentityManager; import org.picketlink.idm.model.Attribute; -import org.picketlink.idm.model.annotation.AttributeProperty; import org.picketlink.idm.model.sample.User; import java.util.HashMap; diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/mappings/ApplicationData.java b/services/src/main/java/org/keycloak/services/models/picketlink/mappings/ApplicationData.java index 9157ae39dd..f515f2875d 100755 --- a/services/src/main/java/org/keycloak/services/models/picketlink/mappings/ApplicationData.java +++ b/services/src/main/java/org/keycloak/services/models/picketlink/mappings/ApplicationData.java @@ -1,6 +1,5 @@ package org.keycloak.services.models.picketlink.mappings; -import org.picketlink.idm.jpa.annotations.AttributeValue; import org.picketlink.idm.model.AbstractPartition; import org.picketlink.idm.model.annotation.AttributeProperty; import org.picketlink.idm.model.sample.User; diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/mappings/RealmData.java b/services/src/main/java/org/keycloak/services/models/picketlink/mappings/RealmData.java index 1fc6b7f54a..860ea7e6fd 100755 --- a/services/src/main/java/org/keycloak/services/models/picketlink/mappings/RealmData.java +++ b/services/src/main/java/org/keycloak/services/models/picketlink/mappings/RealmData.java @@ -1,6 +1,5 @@ package org.keycloak.services.models.picketlink.mappings; -import org.picketlink.idm.jpa.annotations.AttributeValue; import org.picketlink.idm.model.AbstractPartition; import org.picketlink.idm.model.annotation.AttributeProperty; diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/relationships/RealmAdminRelationship.java b/services/src/main/java/org/keycloak/services/models/picketlink/relationships/RealmAdminRelationship.java index 59da8f881d..ab284ba425 100755 --- a/services/src/main/java/org/keycloak/services/models/picketlink/relationships/RealmAdminRelationship.java +++ b/services/src/main/java/org/keycloak/services/models/picketlink/relationships/RealmAdminRelationship.java @@ -1,10 +1,8 @@ package org.keycloak.services.models.picketlink.relationships; -import org.keycloak.services.models.picketlink.mappings.RealmData; import org.picketlink.idm.model.AbstractAttributedType; import org.picketlink.idm.model.Attribute; import org.picketlink.idm.model.Relationship; -import org.picketlink.idm.model.annotation.AttributeProperty; import org.picketlink.idm.model.sample.User; import org.picketlink.idm.query.AttributeParameter; import org.picketlink.idm.query.RelationshipQueryParameter; diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java old mode 100644 new mode 100755 index 96f8564761..60faa761d5 --- a/services/src/main/java/org/keycloak/services/resources/AccountService.java +++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java @@ -21,18 +21,6 @@ */ package org.keycloak.services.resources; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -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; -import javax.ws.rs.core.UriInfo; -import javax.ws.rs.core.Response.Status; - import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.services.managers.AuthenticationManager; @@ -45,6 +33,13 @@ import org.keycloak.services.resources.flows.FormFlows; import org.keycloak.services.validation.Validation; import org.picketlink.idm.credential.util.TimeBasedOTP; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.*; +import javax.ws.rs.core.Response.Status; + /** * @author Stian Thorgersen */ @@ -70,184 +65,151 @@ public class AccountService { @Path("access") @GET public Response accessPage() { - return new Transaction() { - protected Response callImpl() { - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - return Flows.forms(realm, request).setUser(user).forwardToAccess(); - } else { - return Response.status(Status.FORBIDDEN).build(); - } - } - }.call(); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + return Flows.forms(realm, request).setUser(user).forwardToAccess(); + } else { + return Response.status(Status.FORBIDDEN).build(); + } } @Path("") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processAccountUpdate(final MultivaluedMap formData) { - return new Transaction() { - protected Response callImpl() { - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - user.setFirstName(formData.getFirst("firstName")); - user.setLastName(formData.getFirst("lastName")); - user.setEmail(formData.getFirst("email")); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + user.setFirstName(formData.getFirst("firstName")); + user.setLastName(formData.getFirst("lastName")); + user.setEmail(formData.getFirst("email")); - return Flows.forms(realm, request).setUser(user).forwardToAccount(); - } else { - return Response.status(Status.FORBIDDEN).build(); - } - } - }.call(); + return Flows.forms(realm, request).setUser(user).forwardToAccount(); + } else { + return Response.status(Status.FORBIDDEN).build(); + } } @Path("totp") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processTotpUpdate(final MultivaluedMap formData) { - return new Transaction() { - protected Response callImpl() { - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - FormFlows forms = Flows.forms(realm, request); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + FormFlows forms = Flows.forms(realm, request); - String totp = formData.getFirst("totp"); - String totpSecret = formData.getFirst("totpSecret"); + String totp = formData.getFirst("totp"); + String totpSecret = formData.getFirst("totpSecret"); - String error = null; + String error = null; - if (Validation.isEmpty(totp)) { - error = Messages.MISSING_TOTP; - } else if (!new TimeBasedOTP().validate(totp, totpSecret.getBytes())) { - error = Messages.INVALID_TOTP; - } - - if (error != null) { - return forms.setError(error).forwardToTotp(); - } - - UserCredentialModel credentials = new UserCredentialModel(); - credentials.setType(CredentialRepresentation.TOTP); - credentials.setValue(formData.getFirst("totpSecret")); - realm.updateCredential(user, credentials); - - if (!user.isEnabled() && "REQUIRED".equals(user.getAttribute("KEYCLOAK_TOTP"))) { - user.setEnabled(true); - } - - user.setAttribute("KEYCLOAK_TOTP", "ENABLED"); - - return Flows.forms(realm, request).setUser(user).forwardToTotp(); - } else { - return Response.status(Status.FORBIDDEN).build(); - } + if (Validation.isEmpty(totp)) { + error = Messages.MISSING_TOTP; + } else if (!new TimeBasedOTP().validate(totp, totpSecret.getBytes())) { + error = Messages.INVALID_TOTP; } - }.call(); + + if (error != null) { + return forms.setError(error).forwardToTotp(); + } + + UserCredentialModel credentials = new UserCredentialModel(); + credentials.setType(CredentialRepresentation.TOTP); + credentials.setValue(formData.getFirst("totpSecret")); + realm.updateCredential(user, credentials); + + if (!user.isEnabled() && "REQUIRED".equals(user.getAttribute("KEYCLOAK_TOTP"))) { + user.setEnabled(true); + } + + user.setAttribute("KEYCLOAK_TOTP", "ENABLED"); + + return Flows.forms(realm, request).setUser(user).forwardToTotp(); + } else { + return Response.status(Status.FORBIDDEN).build(); + } } @Path("password") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processPasswordUpdate(final MultivaluedMap formData) { - return new Transaction() { - protected Response callImpl() { - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - FormFlows forms = Flows.forms(realm, request).setUser(user); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + FormFlows forms = Flows.forms(realm, request).setUser(user); - String password = formData.getFirst("password"); - String passwordNew = formData.getFirst("password-new"); - String passwordConfirm = formData.getFirst("password-confirm"); + String password = formData.getFirst("password"); + String passwordNew = formData.getFirst("password-new"); + String passwordConfirm = formData.getFirst("password-confirm"); - String error = null; + String error = null; - if (Validation.isEmpty(password)) { - error = Messages.MISSING_PASSWORD; - } else if (Validation.isEmpty(passwordNew)) { - error = Messages.MISSING_PASSWORD; - } else if (!passwordNew.equals(passwordConfirm)) { - error = Messages.INVALID_PASSWORD_CONFIRM; - } else if (!realm.validatePassword(user, password)) { - error = Messages.INVALID_PASSWORD_EXISTING; - } - - if (error != null) { - return forms.setError(error).forwardToPassword(); - } - - UserCredentialModel credentials = new UserCredentialModel(); - credentials.setType(CredentialRepresentation.PASSWORD); - credentials.setValue(passwordNew); - - realm.updateCredential(user, credentials); - - return Flows.forms(realm, request).setUser(user).forwardToPassword(); - } else { - return Response.status(Status.FORBIDDEN).build(); - } + if (Validation.isEmpty(password)) { + error = Messages.MISSING_PASSWORD; + } else if (Validation.isEmpty(passwordNew)) { + error = Messages.MISSING_PASSWORD; + } else if (!passwordNew.equals(passwordConfirm)) { + error = Messages.INVALID_PASSWORD_CONFIRM; + } else if (!realm.validatePassword(user, password)) { + error = Messages.INVALID_PASSWORD_EXISTING; } - }.call(); + + if (error != null) { + return forms.setError(error).forwardToPassword(); + } + + UserCredentialModel credentials = new UserCredentialModel(); + credentials.setType(CredentialRepresentation.PASSWORD); + credentials.setValue(passwordNew); + + realm.updateCredential(user, credentials); + + return Flows.forms(realm, request).setUser(user).forwardToPassword(); + } else { + return Response.status(Status.FORBIDDEN).build(); + } } @Path("") @GET public Response accountPage() { - return new Transaction() { - protected Response callImpl() { - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - return Flows.forms(realm, request).setUser(user).forwardToAccount(); - } else { - return Response.status(Status.FORBIDDEN).build(); - } - } - }.call(); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + return Flows.forms(realm, request).setUser(user).forwardToAccount(); + } else { + return Response.status(Status.FORBIDDEN).build(); + } } @Path("social") @GET public Response socialPage() { - return new Transaction() { - protected Response callImpl() { - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - return Flows.forms(realm, request).setUser(user).forwardToSocial(); - } else { - return Response.status(Status.FORBIDDEN).build(); - } - } - }.call(); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + return Flows.forms(realm, request).setUser(user).forwardToSocial(); + } else { + return Response.status(Status.FORBIDDEN).build(); + } } @Path("totp") @GET public Response totpPage() { - return new Transaction() { - protected Response callImpl() { - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - return Flows.forms(realm, request).setUser(user).forwardToTotp(); - } else { - return Response.status(Status.FORBIDDEN).build(); - } - } - }.call(); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + return Flows.forms(realm, request).setUser(user).forwardToTotp(); + } else { + return Response.status(Status.FORBIDDEN).build(); + } } @Path("password") @GET public Response passwordPage() { - return new Transaction() { - protected Response callImpl() { - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - return Flows.forms(realm, request).setUser(user).forwardToPassword(); - } else { - return Response.status(Status.FORBIDDEN).build(); - } - } - }.call(); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + return Flows.forms(realm, request).setUser(user).forwardToPassword(); + } else { + return Response.status(Status.FORBIDDEN).build(); + } } - } 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 cd464248f7..104803ca39 100755 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -1,7 +1,6 @@ package org.keycloak.services.resources; import org.keycloak.SkeletonKeyContextResolver; -import org.keycloak.services.filters.KeycloakSessionCleanupFilter; import org.keycloak.services.managers.TokenManager; import org.keycloak.services.models.KeycloakSessionFactory; import org.keycloak.services.models.picketlink.PicketlinkKeycloakSession; @@ -13,25 +12,15 @@ import org.picketlink.idm.PartitionManager; import org.picketlink.idm.config.IdentityConfigurationBuilder; import org.picketlink.idm.internal.DefaultPartitionManager; import org.picketlink.idm.jpa.internal.JPAContextInitializer; -import org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity; -import org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity; +import org.picketlink.idm.jpa.model.sample.simple.*; import javax.annotation.PreDestroy; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; +import javax.servlet.ServletContext; import javax.ws.rs.core.Application; +import javax.ws.rs.core.Context; import java.util.HashSet; import java.util.Set; @@ -45,10 +34,11 @@ public class KeycloakApplication extends Application { protected KeycloakSessionFactory factory; - public KeycloakApplication() { + public KeycloakApplication(@Context ServletContext context) { KeycloakSessionFactory f = createSessionFactory(); this.factory = f; - classes.add(KeycloakSessionCleanupFilter.class); + context.setAttribute(KeycloakSessionFactory.class.getName(), factory); + //classes.add(KeycloakSessionCleanupFilter.class); TokenManager tokenManager = new TokenManager(); @@ -56,6 +46,7 @@ public class KeycloakApplication extends Application { singletons.add(new SocialResource(tokenManager, new SocialRequestManager())); classes.add(SkeletonKeyContextResolver.class); classes.add(SaasService.class); + } protected KeycloakSessionFactory createSessionFactory() { diff --git a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java index 7085eab839..e5550a0734 100755 --- a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java +++ b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java @@ -3,7 +3,6 @@ package org.keycloak.services.resources; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.logging.Logger; import org.keycloak.representations.idm.PublishedRealmRepresentation; -import org.keycloak.services.models.KeycloakSession; import org.keycloak.services.models.RealmModel; import javax.ws.rs.GET; @@ -41,11 +40,7 @@ public class PublicRealmResource { @NoCache @Produces("application/json") public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) { - return new Transaction() { - protected PublishedRealmRepresentation callImpl() { - return realmRep(realm, uriInfo); - } - }.call(); + return realmRep(realm, uriInfo); } @GET @@ -53,26 +48,22 @@ public class PublicRealmResource { @Path("html") @Produces("text/html") public String getRealmHtml(@PathParam("realm") String id) { - return new Transaction() { - protected String callImpl() { - StringBuffer html = new StringBuffer(); + StringBuffer html = new StringBuffer(); - String authUri = TokenService.loginPageUrl(uriInfo).build(realm.getId()).toString(); - String codeUri = TokenService.accessCodeToTokenUrl(uriInfo).build(realm.getId()).toString(); - String grantUrl = TokenService.grantAccessTokenUrl(uriInfo).build(realm.getId()).toString(); - String idGrantUrl = TokenService.grantIdentityTokenUrl(uriInfo).build(realm.getId()).toString(); + String authUri = TokenService.loginPageUrl(uriInfo).build(realm.getId()).toString(); + String codeUri = TokenService.accessCodeToTokenUrl(uriInfo).build(realm.getId()).toString(); + String grantUrl = TokenService.grantAccessTokenUrl(uriInfo).build(realm.getId()).toString(); + String idGrantUrl = TokenService.grantIdentityTokenUrl(uriInfo).build(realm.getId()).toString(); - html.append("

Realm: ").append(realm.getName()).append("

"); - html.append("

auth: ").append(authUri).append("

"); - html.append("

code: ").append(codeUri).append("

"); - html.append("

grant: ").append(grantUrl).append("

"); - html.append("

identity grant: ").append(idGrantUrl).append("

"); - html.append("

public key: ").append(realm.getPublicKeyPem()).append("

"); - html.append(""); + html.append("

Realm: ").append(realm.getName()).append("

"); + html.append("

auth: ").append(authUri).append("

"); + html.append("

code: ").append(codeUri).append("

"); + html.append("

grant: ").append(grantUrl).append("

"); + html.append("

identity grant: ").append(idGrantUrl).append("

"); + html.append("

public key: ").append(realm.getPublicKeyPem()).append("

"); + html.append(""); - return html.toString(); - } - }.call(); + return html.toString(); } 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 b580484ea2..7ed4c14908 100755 --- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java @@ -1,26 +1,17 @@ package org.keycloak.services.resources; import org.jboss.resteasy.logging.Logger; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.TokenManager; +import org.keycloak.services.models.KeycloakSession; import org.keycloak.services.models.RealmModel; -import org.keycloak.services.models.RoleModel; -import org.keycloak.services.models.UserModel; -import org.keycloak.social.SocialRequestManager; -import javax.ws.rs.Consumes; -import javax.ws.rs.NotAuthorizedException; import javax.ws.rs.NotFoundException; -import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.container.ResourceContext; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; @@ -39,7 +30,10 @@ public class RealmsResource { protected HttpHeaders headers; @Context - ResourceContext resourceContext; + protected ResourceContext resourceContext; + + @Context + protected KeycloakSession session; protected TokenManager tokenManager; @@ -53,57 +47,41 @@ public class RealmsResource { @Path("{realm}/tokens") public TokenService getTokenService(final @PathParam("realm") String id) { - return new Transaction(false) { - @Override - protected TokenService callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.getRealm(id); - if (realm == null) { - logger.debug("realm not found"); - throw new NotFoundException(); - } - TokenService tokenService = new TokenService(realm, tokenManager); - resourceContext.initResource(tokenService); - return tokenService; - } - }.call(); - + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.getRealm(id); + if (realm == null) { + logger.debug("realm not found"); + throw new NotFoundException(); + } + TokenService tokenService = new TokenService(realm, tokenManager); + resourceContext.initResource(tokenService); + return tokenService; } @Path("{realm}/account") public AccountService getAccountService(final @PathParam("realm") String id) { - return new Transaction(false) { - @Override - protected AccountService callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.getRealm(id); - if (realm == null) { - logger.debug("realm not found"); - throw new NotFoundException(); - } - AccountService accountService = new AccountService(realm); - resourceContext.initResource(accountService); - return accountService; - } - }.call(); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.getRealm(id); + if (realm == null) { + logger.debug("realm not found"); + throw new NotFoundException(); + } + AccountService accountService = new AccountService(realm); + resourceContext.initResource(accountService); + return accountService; } @Path("{realm}") public PublicRealmResource getRealmResource(final @PathParam("realm") String id) { - return new Transaction(false) { - @Override - protected PublicRealmResource callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.getRealm(id); - if (realm == null) { - logger.debug("realm not found"); - throw new NotFoundException(); - } - PublicRealmResource realmResource = new PublicRealmResource(realm); - resourceContext.initResource(realmResource); - return realmResource; - } - }.call(); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.getRealm(id); + if (realm == null) { + logger.debug("realm not found"); + throw new NotFoundException(); + } + PublicRealmResource realmResource = new PublicRealmResource(realm); + resourceContext.initResource(realmResource); + return realmResource; } 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 7b5a151a66..c1c7758aae 100755 --- a/services/src/main/java/org/keycloak/services/resources/SaasService.java +++ b/services/src/main/java/org/keycloak/services/resources/SaasService.java @@ -10,18 +10,14 @@ import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.messages.Messages; -import org.keycloak.services.models.RealmModel; -import org.keycloak.services.models.RequiredCredentialModel; -import org.keycloak.services.models.RoleModel; -import org.keycloak.services.models.UserCredentialModel; -import org.keycloak.services.models.UserModel; +import org.keycloak.services.models.*; import org.keycloak.services.resources.admin.RealmsAdminResource; import org.keycloak.services.resources.flows.Flows; import org.keycloak.services.validation.Validation; import javax.ws.rs.*; +import javax.ws.rs.container.ResourceContext; import javax.ws.rs.core.*; - import java.net.URI; import java.util.LinkedList; import java.util.List; @@ -44,7 +40,13 @@ public class SaasService { protected HttpRequest request; @Context - HttpResponse response; + protected HttpResponse response; + + @Context + protected KeycloakSession session; + + @Context + protected ResourceContext resourceContext; protected String adminPath = "/saas/admin/index.html"; protected AuthenticationManager authManager = new AuthenticationManager(); @@ -82,22 +84,17 @@ public class SaasService { @GET @NoCache public Response keepalive(final @Context HttpHeaders headers) { - logger.info("keepalive"); - return new Transaction() { - @Override - public Response callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.defaultRealm(); - if (realm == null) - throw new NotFoundException(); - UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers); - if (user == null) { - return Response.status(401).build(); - } - NewCookie refreshCookie = authManager.createSaasIdentityCookie(realm, user, uriInfo); - return Response.noContent().cookie(refreshCookie).build(); - } - }.call(); + logger.debug("keepalive"); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.defaultRealm(); + if (realm == null) + throw new NotFoundException(); + UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers); + if (user == null) { + return Response.status(401).build(); + } + NewCookie refreshCookie = authManager.createSaasIdentityCookie(realm, user, uriInfo); + return Response.noContent().cookie(refreshCookie).build(); } @Path("whoami") @@ -105,20 +102,15 @@ public class SaasService { @Produces("application/json") @NoCache public Response whoAmI(final @Context HttpHeaders headers) { - return new Transaction() { - @Override - public Response callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.defaultRealm(); - if (realm == null) - throw new NotFoundException(); - UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers); - if (user == null) { - return Response.status(401).build(); - } - return Response.ok(new WhoAmI(user.getLoginName(), user.getFirstName() + " " + user.getLastName())).build(); - } - }.call(); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.defaultRealm(); + if (realm == null) + throw new NotFoundException(); + UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers); + if (user == null) { + return Response.status(401).build(); + } + return Response.ok(new WhoAmI(user.getLoginName(), user.getFirstName() + " " + user.getLastName())).build(); } @Path("isLoggedIn.js") @@ -126,24 +118,19 @@ public class SaasService { @Produces("application/javascript") @NoCache public String isLoggedIn(final @Context HttpHeaders headers) { - return new Transaction() { - @Override - public String callImpl() { - logger.info("WHOAMI Javascript start."); - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.defaultRealm(); - if (realm == null) { - return "var keycloakCookieLoggedIn = false;"; + logger.debug("WHOAMI Javascript start."); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.defaultRealm(); + if (realm == null) { + return "var keycloakCookieLoggedIn = false;"; - } - UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers); - if (user == null) { - return "var keycloakCookieLoggedIn = false;"; - } - logger.info("WHOAMI: " + user.getLoginName()); - return "var keycloakCookieLoggedIn = true;"; - } - }.call(); + } + UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers); + if (user == null) { + return "var keycloakCookieLoggedIn = false;"; + } + logger.debug("WHOAMI: " + user.getLoginName()); + return "var keycloakCookieLoggedIn = true;"; } public static UriBuilder contextRoot(UriInfo uriInfo) { @@ -156,86 +143,63 @@ public class SaasService { @Path("admin/realms") public RealmsAdminResource getRealmsAdmin(@Context final HttpHeaders headers) { - return new Transaction(false) { - @Override - protected RealmsAdminResource callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel saasRealm = realmManager.defaultRealm(); - if (saasRealm == null) - throw new NotFoundException(); - UserModel admin = authManager.authenticateSaasIdentity(saasRealm, uriInfo, headers); - if (admin == null) { - throw new NotAuthorizedException("Bearer"); - } - RoleModel creatorRole = saasRealm.getRole(SaasService.REALM_CREATOR_ROLE); - if (!saasRealm.hasRole(admin, creatorRole)) { - logger.warn("not a Realm creator"); - throw new NotAuthorizedException("Bearer"); - } - return new RealmsAdminResource(admin); - } - }.call(); + RealmManager realmManager = new RealmManager(session); + RealmModel saasRealm = realmManager.defaultRealm(); + if (saasRealm == null) + throw new NotFoundException(); + UserModel admin = authManager.authenticateSaasIdentity(saasRealm, uriInfo, headers); + if (admin == null) { + throw new NotAuthorizedException("Bearer"); + } + RoleModel creatorRole = saasRealm.getRole(SaasService.REALM_CREATOR_ROLE); + if (!saasRealm.hasRole(admin, creatorRole)) { + logger.warn("not a Realm creator"); + throw new NotAuthorizedException("Bearer"); + } + RealmsAdminResource adminResource = new RealmsAdminResource(admin); + resourceContext.initResource(adminResource); + return adminResource; } @Path("login") @GET @NoCache public void loginPage() { - new Transaction() { - @Override - protected void runImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.defaultRealm(); - authManager.expireSaasIdentityCookie(uriInfo); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.defaultRealm(); + authManager.expireSaasIdentityCookie(uriInfo); - Flows.forms(realm, request).forwardToLogin(); - } - }.run(); + Flows.forms(realm, request).forwardToLogin(); } @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); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.defaultRealm(); + authManager.expireSaasIdentityCookie(uriInfo); - Flows.forms(realm, request).forwardToRegistration(); - } - }.run(); + Flows.forms(realm, request).forwardToRegistration(); } @Path("logout") @GET @NoCache public void logout() { - new Transaction() { - @Override - protected void runImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.defaultRealm(); - authManager.expireSaasIdentityCookie(uriInfo); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.defaultRealm(); + authManager.expireSaasIdentityCookie(uriInfo); - Flows.forms(realm, request).forwardToLogin(); - } - }.run(); + Flows.forms(realm, request).forwardToLogin(); } @Path("logout-cookie") @GET @NoCache public void logoutCookie() { - logger.info("*** logoutCookie"); - new Transaction() { - @Override - protected void runImpl() { - authManager.expireSaasIdentityCookie(uriInfo); - } - }.run(); + logger.debug("*** logoutCookie"); + authManager.expireSaasIdentityCookie(uriInfo); } @Path("login") @@ -243,132 +207,117 @@ public class SaasService { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processLogin(final MultivaluedMap formData) { logger.info("processLogin start"); - return new Transaction() { - @Override - protected Response callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.defaultRealm(); - if (realm == null) - throw new NotFoundException(); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.defaultRealm(); + if (realm == null) + throw new NotFoundException(); - if (!realm.isEnabled()) { - throw new NotImplementedYetException(); - } - String username = formData.getFirst("username"); - UserModel user = realm.getUser(username); - if (user == null) { - logger.info("Not Authenticated! Incorrect user name"); + if (!realm.isEnabled()) { + throw new NotImplementedYetException(); + } + String username = formData.getFirst("username"); + UserModel user = realm.getUser(username); + if (user == null) { + logger.info("Not Authenticated! Incorrect user name"); - return Flows.forms(realm, request).setError(Messages.INVALID_USER).setFormData(formData) - .forwardToLogin(); - } - if (!user.isEnabled()) { - logger.info("Account is disabled, contact admin."); + return Flows.forms(realm, request).setError(Messages.INVALID_USER).setFormData(formData) + .forwardToLogin(); + } + if (!user.isEnabled()) { + logger.info("Account is disabled, contact admin."); - return Flows.forms(realm, request).setError(Messages.ACCOUNT_DISABLED) - .setFormData(formData).forwardToLogin(); - } + return Flows.forms(realm, request).setError(Messages.ACCOUNT_DISABLED) + .setFormData(formData).forwardToLogin(); + } - boolean authenticated = authManager.authenticateForm(realm, user, formData); - if (!authenticated) { - logger.info("Not Authenticated! Invalid credentials"); + boolean authenticated = authManager.authenticateForm(realm, user, formData); + if (!authenticated) { + logger.info("Not Authenticated! Invalid credentials"); - return Flows.forms(realm, request).setError(Messages.INVALID_PASSWORD).setFormData(formData) - .forwardToLogin(); - } + return Flows.forms(realm, request).setError(Messages.INVALID_PASSWORD).setFormData(formData) + .forwardToLogin(); + } - NewCookie cookie = authManager.createSaasIdentityCookie(realm, user, uriInfo); - return Response.status(302).cookie(cookie).location(contextRoot(uriInfo).path(adminPath).build()).build(); - } - }.call(); + NewCookie cookie = authManager.createSaasIdentityCookie(realm, user, uriInfo); + return Response.status(302).cookie(cookie).location(contextRoot(uriInfo).path(adminPath).build()).build(); } @Path("registrations") @POST @Consumes(MediaType.APPLICATION_JSON) public Response register(final UserRepresentation newUser) { - return new Transaction() { - @Override - protected Response callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel defaultRealm = realmManager.defaultRealm(); - UserModel user = registerMe(defaultRealm, newUser); - if (user == null) { - return Response.status(400).type("text/plain").entity("Already exists").build(); - } - URI uri = uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(user.getLoginName()).build(); - return Response.created(uri).build(); - } - }.call(); + RealmManager realmManager = new RealmManager(session); + RealmModel defaultRealm = realmManager.defaultRealm(); + UserModel user = registerMe(defaultRealm, newUser); + if (user == null) { + return Response.status(400).type("text/plain").entity("Already exists").build(); + } + URI uri = uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(user.getLoginName()).build(); + return Response.created(uri).build(); } @Path("registrations") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processRegister(final MultivaluedMap formData) { - return new Transaction() { - @Override - protected Response callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel defaultRealm = realmManager.defaultRealm(); + RealmManager realmManager = new RealmManager(session); + RealmModel defaultRealm = realmManager.defaultRealm(); - List requiredCredentialTypes = new LinkedList(); - for (RequiredCredentialModel m : defaultRealm.getRequiredCredentials()) { - requiredCredentialTypes.add(m.getType()); - } + List requiredCredentialTypes = new LinkedList(); + for (RequiredCredentialModel m : defaultRealm.getRequiredCredentials()) { + requiredCredentialTypes.add(m.getType()); + } - String error = Validation.validateRegistrationForm(formData, requiredCredentialTypes); - if (error != null) { - return Flows.forms(defaultRealm, request).setError(error).setFormData(formData) - .forwardToRegistration(); - } + String error = Validation.validateRegistrationForm(formData, requiredCredentialTypes); + if (error != null) { + return Flows.forms(defaultRealm, request).setError(error).setFormData(formData) + .forwardToRegistration(); + } - UserRepresentation newUser = new UserRepresentation(); - newUser.setUsername(formData.getFirst("username")); - newUser.setEmail(formData.getFirst("email")); + UserRepresentation newUser = new UserRepresentation(); + 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; - String last = ""; - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - if (tokenizer.hasMoreTokens()) { - if (first == null) { - first = new StringBuffer(); - } else { - first.append(" "); - } - first.append(token); - } else { - last = token; - } - } - if (first == null) + String fullname = formData.getFirst("name"); + if (fullname != null) { + StringTokenizer tokenizer = new StringTokenizer(fullname, " "); + StringBuffer first = null; + String last = ""; + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if (tokenizer.hasMoreTokens()) { + if (first == null) { first = new StringBuffer(); - newUser.setFirstName(first.toString()); - newUser.setLastName(last); + } else { + first.append(" "); + } + first.append(token); + } else { + last = token; } - - if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) { - newUser.credential(CredentialRepresentation.PASSWORD, formData.getFirst("password")); - } - - if (requiredCredentialTypes.contains(CredentialRepresentation.TOTP)) { - newUser.credential(CredentialRepresentation.TOTP, formData.getFirst("password")); - } - - UserModel user = registerMe(defaultRealm, newUser); - if (user == null) { - return Flows.forms(defaultRealm, request).setError(Messages.USERNAME_EXISTS) - .setFormData(formData).forwardToRegistration(); - - } - NewCookie cookie = authManager.createSaasIdentityCookie(defaultRealm, user, uriInfo); - return Response.status(302).location(contextRoot(uriInfo).path(adminPath).build()).cookie(cookie).build(); } - }.call(); + if (first == null) + first = new StringBuffer(); + newUser.setFirstName(first.toString()); + newUser.setLastName(last); + } + + if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) { + newUser.credential(CredentialRepresentation.PASSWORD, formData.getFirst("password")); + } + + if (requiredCredentialTypes.contains(CredentialRepresentation.TOTP)) { + newUser.credential(CredentialRepresentation.TOTP, formData.getFirst("password")); + } + + UserModel user = registerMe(defaultRealm, newUser); + if (user == null) { + return Flows.forms(defaultRealm, request).setError(Messages.USERNAME_EXISTS) + .setFormData(formData).forwardToRegistration(); + + } + NewCookie cookie = authManager.createSaasIdentityCookie(defaultRealm, user, uriInfo); + return Response.status(302).location(contextRoot(uriInfo).path(adminPath).build()).cookie(cookie).build(); } protected UserModel registerMe(RealmModel defaultRealm, UserRepresentation newUser) { diff --git a/services/src/main/java/org/keycloak/services/resources/SocialResource.java b/services/src/main/java/org/keycloak/services/resources/SocialResource.java old mode 100644 new mode 100755 index 73e139cf8e..1bcac8b7ac --- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java +++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java @@ -21,12 +21,19 @@ */ package org.keycloak.services.resources; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; +import org.jboss.resteasy.logging.Logger; +import org.jboss.resteasy.spi.HttpRequest; +import org.keycloak.services.managers.AuthenticationManager; +import org.keycloak.services.managers.RealmManager; +import org.keycloak.services.managers.TokenManager; +import org.keycloak.services.models.KeycloakSession; +import org.keycloak.services.models.RealmModel; +import org.keycloak.services.models.RoleModel; +import org.keycloak.services.models.UserModel; +import org.keycloak.services.resources.flows.Flows; +import org.keycloak.services.resources.flows.OAuthFlows; +import org.keycloak.services.resources.flows.Urls; +import org.keycloak.social.*; import javax.imageio.spi.ServiceRegistry; import javax.ws.rs.GET; @@ -38,27 +45,12 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; - -import org.jboss.resteasy.logging.Logger; -import org.jboss.resteasy.spi.HttpRequest; -import org.keycloak.services.managers.AuthenticationManager; -import org.keycloak.services.managers.RealmManager; -import org.keycloak.services.managers.TokenManager; -import org.keycloak.services.models.RealmModel; -import org.keycloak.services.models.RoleModel; -import org.keycloak.services.models.UserModel; -import org.keycloak.services.resources.flows.Flows; -import org.keycloak.services.resources.flows.OAuthFlows; -import org.keycloak.services.resources.flows.Urls; -import org.keycloak.social.AuthCallback; -import org.keycloak.social.AuthRequest; -import org.keycloak.social.RequestDetails; -import org.keycloak.social.RequestDetailsBuilder; -import org.keycloak.social.SocialProvider; -import org.keycloak.social.SocialProviderConfig; -import org.keycloak.social.SocialProviderException; -import org.keycloak.social.SocialRequestManager; -import org.keycloak.social.SocialUser; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; /** * @author Stian Thorgersen @@ -77,11 +69,14 @@ public class SocialResource { @Context private HttpRequest request; - private SocialRequestManager socialRequestManager; + @Context + protected KeycloakSession session; - private TokenManager tokenManager; + protected SocialRequestManager socialRequestManager; - private AuthenticationManager authManager = new AuthenticationManager(); + protected TokenManager tokenManager; + + protected AuthenticationManager authManager = new AuthenticationManager(); public SocialResource(TokenManager tokenManager, SocialRequestManager socialRequestManager) { this.tokenManager = tokenManager; @@ -91,82 +86,78 @@ public class SocialResource { @GET @Path("callback") public Response callback() throws URISyntaxException { - return new Transaction() { - protected Response callImpl() { - Map queryParams = getQueryParams(); + Map queryParams = getQueryParams(); - RequestDetails requestData = getRequestDetails(queryParams); - SocialProvider provider = getProvider(requestData.getProviderId()); + RequestDetails requestData = getRequestDetails(queryParams); + SocialProvider provider = getProvider(requestData.getProviderId()); - String realmId = requestData.getClientAttribute("realmId"); + String realmId = requestData.getClientAttribute("realmId"); - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.getRealm(realmId); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.getRealm(realmId); - OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); + OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); - if (!realm.isEnabled()) { - return oauth.forwardToSecurityFailure("Realm not enabled."); - } + if (!realm.isEnabled()) { + return oauth.forwardToSecurityFailure("Realm not enabled."); + } - if (!realm.isEnabled()) { - return oauth.forwardToSecurityFailure("Realm not enabled."); - } + if (!realm.isEnabled()) { + return oauth.forwardToSecurityFailure("Realm not enabled."); + } - String clientId = requestData.getClientAttributes().get("clientId"); + String clientId = requestData.getClientAttributes().get("clientId"); - UserModel client = realm.getUser(clientId); - if (client == null) { - return oauth.forwardToSecurityFailure("Unknown login requester."); - } - if (!client.isEnabled()) { - return oauth.forwardToSecurityFailure("Login requester not enabled."); - } + UserModel client = realm.getUser(clientId); + if (client == null) { + return oauth.forwardToSecurityFailure("Unknown login requester."); + } + if (!client.isEnabled()) { + return oauth.forwardToSecurityFailure("Login requester not enabled."); + } - String key = System.getProperty("keycloak.social." + requestData.getProviderId() + ".key"); - String secret = System.getProperty("keycloak.social." + requestData.getProviderId() + ".secret"); - String callbackUri = Urls.socialCallback(uriInfo.getBaseUri()).toString(); - SocialProviderConfig config = new SocialProviderConfig(key, secret, callbackUri); + String key = System.getProperty("keycloak.social." + requestData.getProviderId() + ".key"); + String secret = System.getProperty("keycloak.social." + requestData.getProviderId() + ".secret"); + String callbackUri = Urls.socialCallback(uriInfo.getBaseUri()).toString(); + SocialProviderConfig config = new SocialProviderConfig(key, secret, callbackUri); - AuthCallback callback = new AuthCallback(requestData.getSocialAttributes(), queryParams); + AuthCallback callback = new AuthCallback(requestData.getSocialAttributes(), queryParams); - SocialUser socialUser = null; - try { - socialUser = provider.processCallback(config, callback); - } catch (SocialProviderException e) { - logger.warn("Failed to process social callback", e); - return oauth.forwardToSecurityFailure("Failed to process social callback"); - } + SocialUser socialUser = null; + try { + socialUser = provider.processCallback(config, callback); + } catch (SocialProviderException e) { + logger.warn("Failed to process social callback", e); + return oauth.forwardToSecurityFailure("Failed to process social callback"); + } - // TODO Lookup user based on attribute for provider id - this is so a user can have a friendly username + link a - // user to - // multiple social logins - UserModel user = realm.getUser(provider.getId() + "." + socialUser.getId()); + // TODO Lookup user based on attribute for provider id - this is so a user can have a friendly username + link a + // user to + // multiple social logins + UserModel user = realm.getUser(provider.getId() + "." + socialUser.getId()); - if (user == null) { - if (!realm.isRegistrationAllowed()) { - return oauth.forwardToSecurityFailure("Registration not allowed"); - } - - user = realm.addUser(provider.getId() + "." + socialUser.getId()); - user.setAttribute(provider.getId() + ".id", socialUser.getId()); - - for (RoleModel role : realm.getDefaultRoles()) { - realm.grantRole(user, role); - } - } - - if (!user.isEnabled()) { - return oauth.forwardToSecurityFailure("Your account is not enabled."); - } - - String scope = requestData.getClientAttributes().get("scope"); - String state = requestData.getClientAttributes().get("state"); - String redirectUri = requestData.getClientAttributes().get("redirectUri"); - - return oauth.processAccessCode(scope, state, redirectUri, client, user); + if (user == null) { + if (!realm.isRegistrationAllowed()) { + return oauth.forwardToSecurityFailure("Registration not allowed"); } - }.call(); + + user = realm.addUser(provider.getId() + "." + socialUser.getId()); + user.setAttribute(provider.getId() + ".id", socialUser.getId()); + + for (RoleModel role : realm.getDefaultRoles()) { + realm.grantRole(user, role); + } + } + + if (!user.isEnabled()) { + return oauth.forwardToSecurityFailure("Your account is not enabled."); + } + + String scope = requestData.getClientAttributes().get("scope"); + String state = requestData.getClientAttributes().get("state"); + String redirectUri = requestData.getClientAttributes().get("redirectUri"); + + return oauth.processAccessCode(scope, state, redirectUri, client, user); } @GET 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 cb63744aaa..133ebe484b 100755 --- a/services/src/main/java/org/keycloak/services/resources/TokenService.java +++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java @@ -11,48 +11,18 @@ import org.jboss.resteasy.spi.HttpResponse; import org.keycloak.representations.AccessTokenResponse; import org.keycloak.representations.SkeletonKeyToken; import org.keycloak.representations.idm.CredentialRepresentation; -import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.services.managers.AccessCodeEntry; -import org.keycloak.services.managers.AuthenticationManager; -import org.keycloak.services.managers.RealmManager; -import org.keycloak.services.managers.ResourceAdminManager; -import org.keycloak.services.managers.TokenManager; +import org.keycloak.services.managers.*; import org.keycloak.services.messages.Messages; -import org.keycloak.services.models.RealmModel; -import org.keycloak.services.models.RequiredCredentialModel; -import org.keycloak.services.models.RoleModel; -import org.keycloak.services.models.UserCredentialModel; -import org.keycloak.services.models.UserModel; +import org.keycloak.services.models.*; import org.keycloak.services.resources.flows.Flows; import org.keycloak.services.resources.flows.OAuthFlows; import org.keycloak.services.validation.Validation; -import org.picketlink.idm.credential.util.TimeBasedOTP; -import javax.ws.rs.Consumes; -import javax.ws.rs.ForbiddenException; -import javax.ws.rs.GET; -import javax.ws.rs.NotAuthorizedException; -import javax.ws.rs.POST; -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.NewCookie; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.SecurityContext; -import javax.ws.rs.core.UriBuilder; -import javax.ws.rs.core.UriInfo; +import javax.ws.rs.*; +import javax.ws.rs.core.*; import javax.ws.rs.ext.Providers; - import java.security.PrivateKey; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; +import java.util.*; /** * @author Bill Burke @@ -68,16 +38,28 @@ public class TokenService { @Context protected Providers providers; + @Context protected SecurityContext securityContext; + @Context protected UriInfo uriInfo; + @Context protected HttpHeaders headers; + @Context - HttpRequest request; + protected HttpRequest request; + @Context - HttpResponse response; + protected HttpResponse response; + + @Context + protected KeycloakSession session; + + @Context + protected KeycloakTransaction transaction; + private ResourceAdminManager resourceAdminManager = new ResourceAdminManager(); @@ -123,32 +105,28 @@ public class TokenService { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) public Response grantIdentityToken(final MultivaluedMap form) { - return new Transaction() { - protected Response callImpl() { - String username = form.getFirst(AuthenticationManager.FORM_USERNAME); - if (username == null) { - throw new NotAuthorizedException("No user"); - } - if (!realm.isEnabled()) { - throw new NotAuthorizedException("Disabled realm"); - } - UserModel user = realm.getUser(username); - if (user == null) { - throw new NotAuthorizedException("No user"); - } - if (!user.isEnabled()) { - throw new NotAuthorizedException("Disabled user."); - } - if (!authManager.authenticateForm(realm, user, form)) { - throw new NotAuthorizedException("FORM"); - } - tokenManager = new TokenManager(); - SkeletonKeyToken token = authManager.createIdentityToken(realm, username); - String encoded = tokenManager.encodeToken(realm, token); - AccessTokenResponse res = accessTokenResponse(token, encoded); - return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build(); - } - }.call(); + String username = form.getFirst(AuthenticationManager.FORM_USERNAME); + if (username == null) { + throw new NotAuthorizedException("No user"); + } + if (!realm.isEnabled()) { + throw new NotAuthorizedException("Disabled realm"); + } + UserModel user = realm.getUser(username); + if (user == null) { + throw new NotAuthorizedException("No user"); + } + if (!user.isEnabled()) { + throw new NotAuthorizedException("Disabled user."); + } + if (!authManager.authenticateForm(realm, user, form)) { + throw new NotAuthorizedException("FORM"); + } + tokenManager = new TokenManager(); + SkeletonKeyToken token = authManager.createIdentityToken(realm, username); + String encoded = tokenManager.encodeToken(realm, token); + AccessTokenResponse res = accessTokenResponse(token, encoded); + return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build(); } @Path("grants/access") @@ -156,32 +134,27 @@ public class TokenService { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) public Response grantAccessToken(final MultivaluedMap form) { - return new Transaction() { - protected Response callImpl() { - String username = form.getFirst(AuthenticationManager.FORM_USERNAME); - if (username == null) { - throw new NotAuthorizedException("No user"); - } - if (!realm.isEnabled()) { - throw new NotAuthorizedException("Disabled realm"); - } - UserModel user = realm.getUser(username); - if (user == null) { - throw new NotAuthorizedException("No user"); - } - if (!user.isEnabled()) { - throw new NotAuthorizedException("Disabled user."); - } - if (authManager.authenticateForm(realm, user, form)) { - throw new NotAuthorizedException("Auth failed"); - } - SkeletonKeyToken token = tokenManager.createAccessToken(realm, user); - String encoded = tokenManager.encodeToken(realm, token); - AccessTokenResponse res = accessTokenResponse(token, encoded); - return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build(); - } - }.call(); - + String username = form.getFirst(AuthenticationManager.FORM_USERNAME); + if (username == null) { + throw new NotAuthorizedException("No user"); + } + if (!realm.isEnabled()) { + throw new NotAuthorizedException("Disabled realm"); + } + UserModel user = realm.getUser(username); + if (user == null) { + throw new NotAuthorizedException("No user"); + } + if (!user.isEnabled()) { + throw new NotAuthorizedException("Disabled user."); + } + if (authManager.authenticateForm(realm, user, form)) { + throw new NotAuthorizedException("Auth failed"); + } + SkeletonKeyToken token = tokenManager.createAccessToken(realm, user); + String encoded = tokenManager.encodeToken(realm, token); + AccessTokenResponse res = accessTokenResponse(token, encoded); + return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build(); } @Path("auth/request/login") @@ -190,54 +163,50 @@ public class TokenService { public Response processLogin(@QueryParam("client_id") final String clientId, @QueryParam("scope") final String scopeParam, @QueryParam("state") final String state, @QueryParam("redirect_uri") final String redirect, final MultivaluedMap formData) { - return new Transaction() { - protected Response callImpl() { - OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); + OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); - if (!realm.isEnabled()) { - return oauth.forwardToSecurityFailure("Realm not enabled."); - } - UserModel client = realm.getUser(clientId); - if (client == null) { - return oauth.forwardToSecurityFailure("Unknown login requester."); - } - if (!client.isEnabled()) { - return oauth.forwardToSecurityFailure("Login requester not enabled."); - } - String username = formData.getFirst("username"); - UserModel user = realm.getUser(username); - if (user == null) { - logger.error("Incorrect user name."); + if (!realm.isEnabled()) { + return oauth.forwardToSecurityFailure("Realm not enabled."); + } + UserModel client = realm.getUser(clientId); + if (client == null) { + return oauth.forwardToSecurityFailure("Unknown login requester."); + } + if (!client.isEnabled()) { + return oauth.forwardToSecurityFailure("Login requester not enabled."); + } + String username = formData.getFirst("username"); + UserModel user = realm.getUser(username); + if (user == null) { + logger.error("Incorrect user name."); - return Flows.forms(realm, request).setError(Messages.INVALID_USER).setFormData(formData) - .forwardToLogin(); + return Flows.forms(realm, request).setError(Messages.INVALID_USER).setFormData(formData) + .forwardToLogin(); + } + + if (!user.isEnabled()) { + return oauth.forwardToSecurityFailure("Your account is not enabled."); + } + + if ("ENABLED".equals(user.getAttribute("KEYCLOAK_TOTP")) && Validation.isEmpty(formData.getFirst("totp"))) { + return Flows.forms(realm, request).setFormData(formData).forwardToLoginTotp(); + } else { + for (RequiredCredentialModel c : realm.getRequiredCredentials()) { + if (c.getType().equals(CredentialRepresentation.TOTP)) { + return Flows.forms(realm, request).forwardToTotp(); } - - if (!user.isEnabled()) { - return oauth.forwardToSecurityFailure("Your account is not enabled."); - } - - if ("ENABLED".equals(user.getAttribute("KEYCLOAK_TOTP")) && Validation.isEmpty(formData.getFirst("totp"))) { - return Flows.forms(realm, request).setFormData(formData).forwardToLoginTotp(); - } else { - for (RequiredCredentialModel c : realm.getRequiredCredentials()) { - if (c.getType().equals(CredentialRepresentation.TOTP)) { - return Flows.forms(realm, request).forwardToTotp(); - } - } - } - - boolean authenticated = authManager.authenticateForm(realm, user, formData); - if (!authenticated) { - logger.error("Authentication failed"); - - return Flows.forms(realm, request).setError(Messages.INVALID_PASSWORD).setFormData(formData) - .forwardToLogin(); - } - - return oauth.processAccessCode(scopeParam, state, redirect, client, user); } - }.call(); + } + + boolean authenticated = authManager.authenticateForm(realm, user, formData); + if (!authenticated) { + logger.error("Authentication failed"); + + return Flows.forms(realm, request).setError(Messages.INVALID_PASSWORD).setFormData(formData) + .forwardToLogin(); + } + + return oauth.processAccessCode(scopeParam, state, redirect, client, user); } @Path("registrations") @@ -246,191 +215,181 @@ public class TokenService { public Response processRegister(@QueryParam("client_id") final String clientId, @QueryParam("scope") final String scopeParam, @QueryParam("state") final String state, @QueryParam("redirect_uri") final String redirect, final MultivaluedMap formData) { - return new Transaction() { - @Override - protected Response callImpl() { - OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); + OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); - if (!realm.isEnabled()) { - return oauth.forwardToSecurityFailure("Realm not enabled"); - } - UserModel client = realm.getUser(clientId); - if (client == null) { - return oauth.forwardToSecurityFailure("Unknown login requester."); - } + if (!realm.isEnabled()) { + return oauth.forwardToSecurityFailure("Realm not enabled"); + } + UserModel client = realm.getUser(clientId); + if (client == null) { + return oauth.forwardToSecurityFailure("Unknown login requester."); + } - if (!client.isEnabled()) { - return oauth.forwardToSecurityFailure("Login requester not enabled."); - } + if (!client.isEnabled()) { + return oauth.forwardToSecurityFailure("Login requester not enabled."); + } - if (!realm.isRegistrationAllowed()) { - return oauth.forwardToSecurityFailure("Registration not allowed"); - } + if (!realm.isRegistrationAllowed()) { + return oauth.forwardToSecurityFailure("Registration not allowed"); + } - List requiredCredentialTypes = new LinkedList(); - for (RequiredCredentialModel m : realm.getRequiredCredentials()) { - requiredCredentialTypes.add(m.getType()); - } + List requiredCredentialTypes = new LinkedList(); + for (RequiredCredentialModel m : realm.getRequiredCredentials()) { + requiredCredentialTypes.add(m.getType()); + } - String error = Validation.validateRegistrationForm(formData, requiredCredentialTypes); - if (error != null) { - return Flows.forms(realm, request).setError(error).setFormData(formData).forwardToRegistration(); - } + String error = Validation.validateRegistrationForm(formData, requiredCredentialTypes); + if (error != null) { + return Flows.forms(realm, request).setError(error).setFormData(formData).forwardToRegistration(); + } - String username = formData.getFirst("username"); + String username = formData.getFirst("username"); - UserModel user = realm.getUser(username); - if (user != null) { - return Flows.forms(realm, request).setError(Messages.USERNAME_EXISTS).setFormData(formData) - .forwardToRegistration(); - } + UserModel user = realm.getUser(username); + if (user != null) { + return Flows.forms(realm, request).setError(Messages.USERNAME_EXISTS).setFormData(formData) + .forwardToRegistration(); + } - user = realm.addUser(username); + user = realm.addUser(username); - String fullname = formData.getFirst("name"); - if (fullname != null) { - StringTokenizer tokenizer = new StringTokenizer(fullname, " "); - StringBuffer first = null; - String last = ""; - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - if (tokenizer.hasMoreTokens()) { - if (first == null) { - first = new StringBuffer(); - } else { - first.append(" "); - } - first.append(token); - } else { - last = token; - } - } - if (first == null) + String fullname = formData.getFirst("name"); + if (fullname != null) { + StringTokenizer tokenizer = new StringTokenizer(fullname, " "); + StringBuffer first = null; + String last = ""; + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + if (tokenizer.hasMoreTokens()) { + if (first == null) { first = new StringBuffer(); - user.setFirstName(first.toString()); - user.setLastName(last); + } else { + first.append(" "); + } + first.append(token); + } else { + last = token; } - - user.setEmail(formData.getFirst("email")); - - if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) { - UserCredentialModel credentials = new UserCredentialModel(); - credentials.setType(CredentialRepresentation.PASSWORD); - credentials.setValue(formData.getFirst("password")); - realm.updateCredential(user, credentials); - } - - for (RoleModel role : realm.getDefaultRoles()) { - realm.grantRole(user, role); - } - - return processLogin(clientId, scopeParam, state, redirect, formData); } - }.call(); + if (first == null) + first = new StringBuffer(); + user.setFirstName(first.toString()); + user.setLastName(last); + } + + user.setEmail(formData.getFirst("email")); + + if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) { + UserCredentialModel credentials = new UserCredentialModel(); + credentials.setType(CredentialRepresentation.PASSWORD); + credentials.setValue(formData.getFirst("password")); + realm.updateCredential(user, credentials); + } + + for (RoleModel role : realm.getDefaultRoles()) { + realm.grantRole(user, role); + } + + return processLogin(clientId, scopeParam, state, redirect, formData); } @Path("access/codes") @POST @Produces("application/json") public Response accessCodeToToken(final MultivaluedMap formData) { - return new Transaction() { - protected Response callImpl() { - logger.info("accessRequest <---"); - if (!realm.isEnabled()) { - throw new NotAuthorizedException("Realm not enabled"); - } + logger.info("accessRequest <---"); + if (!realm.isEnabled()) { + throw new NotAuthorizedException("Realm not enabled"); + } - String code = formData.getFirst("code"); - if (code == null) { - logger.debug("code not specified"); - Map error = new HashMap(); - error.put("error", "invalid_request"); - error.put("error_description", "code not specified"); - return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); + String code = formData.getFirst("code"); + if (code == null) { + logger.debug("code not specified"); + Map error = new HashMap(); + error.put("error", "invalid_request"); + error.put("error_description", "code not specified"); + return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); - } - String client_id = formData.getFirst("client_id"); - if (client_id == null) { - logger.debug("client_id not specified"); - Map error = new HashMap(); - error.put("error", "invalid_request"); - error.put("error_description", "client_id not specified"); - return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); - } - UserModel client = realm.getUser(client_id); - if (client == null) { - logger.debug("Could not find user"); - Map error = new HashMap(); - error.put("error", "invalid_client"); - error.put("error_description", "Could not find user"); - return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); - } + } + String client_id = formData.getFirst("client_id"); + if (client_id == null) { + logger.debug("client_id not specified"); + Map error = new HashMap(); + error.put("error", "invalid_request"); + error.put("error_description", "client_id not specified"); + return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); + } + UserModel client = realm.getUser(client_id); + if (client == null) { + logger.debug("Could not find user"); + Map error = new HashMap(); + error.put("error", "invalid_client"); + error.put("error_description", "Could not find user"); + return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); + } - if (!client.isEnabled()) { - logger.debug("user is not enabled"); - Map error = new HashMap(); - error.put("error", "invalid_client"); - error.put("error_description", "User is not enabled"); - return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); - } + if (!client.isEnabled()) { + logger.debug("user is not enabled"); + Map error = new HashMap(); + error.put("error", "invalid_client"); + error.put("error_description", "User is not enabled"); + return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); + } - boolean authenticated = authManager.authenticateForm(realm, client, formData); - if (!authenticated) { - Map error = new HashMap(); - error.put("error", "unauthorized_client"); - return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); - } - - JWSInput input = new JWSInput(code, providers); - boolean verifiedCode = false; - try { - verifiedCode = RSAProvider.verify(input, realm.getPublicKey()); - } catch (Exception ignored) { - logger.debug("Failed to verify signature", ignored); - } - if (!verifiedCode) { - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Unable to verify code signature"); - return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) - .build(); - } - String key = input.readContent(String.class); - AccessCodeEntry accessCode = tokenManager.pullAccessCode(key); - if (accessCode == null) { - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Code not found"); - return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) - .build(); - } - if (accessCode.isExpired()) { - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Code is expired"); - return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) - .build(); - } - if (!accessCode.getToken().isActive()) { - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Token expired"); - return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) - .build(); - } - if (!client.getLoginName().equals(accessCode.getClient().getLoginName())) { - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Auth error"); - return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) - .build(); - } - logger.info("accessRequest SUCCESS"); - AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken()); - return Response.ok(res).build(); - } - }.call(); + boolean authenticated = authManager.authenticateForm(realm, client, formData); + if (!authenticated) { + Map error = new HashMap(); + error.put("error", "unauthorized_client"); + return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); + } + JWSInput input = new JWSInput(code, providers); + boolean verifiedCode = false; + try { + verifiedCode = RSAProvider.verify(input, realm.getPublicKey()); + } catch (Exception ignored) { + logger.debug("Failed to verify signature", ignored); + } + if (!verifiedCode) { + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Unable to verify code signature"); + return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) + .build(); + } + String key = input.readContent(String.class); + AccessCodeEntry accessCode = tokenManager.pullAccessCode(key); + if (accessCode == null) { + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Code not found"); + return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) + .build(); + } + if (accessCode.isExpired()) { + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Code is expired"); + return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) + .build(); + } + if (!accessCode.getToken().isActive()) { + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Token expired"); + return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) + .build(); + } + if (!client.getLoginName().equals(accessCode.getClient().getLoginName())) { + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Auth error"); + return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) + .build(); + } + logger.info("accessRequest SUCCESS"); + AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken()); + return Response.ok(res).build(); } protected AccessTokenResponse accessTokenResponse(PrivateKey privateKey, SkeletonKeyToken token) { @@ -461,47 +420,43 @@ public class TokenService { public Response loginPage(final @QueryParam("response_type") String responseType, final @QueryParam("redirect_uri") String redirect, final @QueryParam("client_id") String clientId, final @QueryParam("scope") String scopeParam, final @QueryParam("state") String state) { - return new Transaction() { - protected Response callImpl() { - OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); + OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); - if (!realm.isEnabled()) { - oauth.forwardToSecurityFailure("Realm not enabled"); - return null; - } - UserModel client = realm.getUser(clientId); - if (client == null) { - oauth.forwardToSecurityFailure("Unknown login requester."); - transaction.rollback(); - return null; - } + if (!realm.isEnabled()) { + oauth.forwardToSecurityFailure("Realm not enabled"); + return null; + } + UserModel client = realm.getUser(clientId); + if (client == null) { + oauth.forwardToSecurityFailure("Unknown login requester."); + transaction.rollback(); + return null; + } - if (!client.isEnabled()) { - oauth.forwardToSecurityFailure("Login requester not enabled."); - transaction.rollback(); - session.close(); - return null; - } + if (!client.isEnabled()) { + oauth.forwardToSecurityFailure("Login requester not enabled."); + transaction.rollback(); + session.close(); + return null; + } - RoleModel resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE); - RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE); - boolean isResource = realm.hasRole(client, resourceRole); - if (!isResource && !realm.hasRole(client, identityRequestRole)) { - oauth.forwardToSecurityFailure("Login requester not allowed to request login."); - transaction.rollback(); - session.close(); - return null; - } + RoleModel resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE); + RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE); + boolean isResource = realm.hasRole(client, resourceRole); + if (!isResource && !realm.hasRole(client, identityRequestRole)) { + oauth.forwardToSecurityFailure("Login requester not allowed to request login."); + transaction.rollback(); + session.close(); + return null; + } - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - logger.info(user.getLoginName() + " already logged in."); - return oauth.processAccessCode(scopeParam, state, redirect, client, user); - } + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + logger.info(user.getLoginName() + " already logged in."); + return oauth.processAccessCode(scopeParam, state, redirect, client, user); + } - return Flows.forms(realm, request).forwardToLogin(); - } - }.call(); + return Flows.forms(realm, request).forwardToLogin(); } @Path("registrations") @@ -509,88 +464,76 @@ public class TokenService { public Response registerPage(final @QueryParam("response_type") String responseType, final @QueryParam("redirect_uri") String redirect, final @QueryParam("client_id") String clientId, final @QueryParam("scope") String scopeParam, final @QueryParam("state") String state) { - return new Transaction() { - protected Response callImpl() { - OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); + OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); - if (!realm.isEnabled()) { - return oauth.forwardToSecurityFailure("Realm not enabled"); - } - UserModel client = realm.getUser(clientId); - if (client == null) { - return oauth.forwardToSecurityFailure("Unknown login requester."); - } + if (!realm.isEnabled()) { + return oauth.forwardToSecurityFailure("Realm not enabled"); + } + UserModel client = realm.getUser(clientId); + if (client == null) { + return oauth.forwardToSecurityFailure("Unknown login requester."); + } - if (!client.isEnabled()) { - return oauth.forwardToSecurityFailure("Login requester not enabled."); - } + if (!client.isEnabled()) { + return oauth.forwardToSecurityFailure("Login requester not enabled."); + } - if (!realm.isRegistrationAllowed()) { - return oauth.forwardToSecurityFailure("Registration not allowed"); - } + if (!realm.isRegistrationAllowed()) { + return oauth.forwardToSecurityFailure("Registration not allowed"); + } - authManager.expireIdentityCookie(realm, uriInfo); + authManager.expireIdentityCookie(realm, uriInfo); - return Flows.forms(realm, request).forwardToRegistration(); - } - }.call(); + return Flows.forms(realm, request).forwardToRegistration(); } @Path("logout") @GET @NoCache public Response logout(final @QueryParam("redirect_uri") String redirectUri) { - return new Transaction() { - protected Response callImpl() { - // todo do we care if anybody can trigger this? + // todo do we care if anybody can trigger this? - UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); - if (user != null) { - logger.info("Logging out: " + user.getLoginName()); - authManager.expireIdentityCookie(realm, uriInfo); - resourceAdminManager.singleLogOut(realm, user.getLoginName()); - } - // todo manage legal redirects - return Response.status(302).location(UriBuilder.fromUri(redirectUri).build()).build(); - } - }.call(); + UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); + if (user != null) { + logger.info("Logging out: " + user.getLoginName()); + authManager.expireIdentityCookie(realm, uriInfo); + resourceAdminManager.singleLogOut(realm, user.getLoginName()); + } + // todo manage legal redirects + return Response.status(302).location(UriBuilder.fromUri(redirectUri).build()).build(); } @Path("oauth/grant") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processOAuth(final MultivaluedMap formData) { - return new Transaction() { - protected Response callImpl() { - OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); + OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); - String code = formData.getFirst("code"); - JWSInput input = new JWSInput(code, providers); - boolean verifiedCode = false; - try { - verifiedCode = RSAProvider.verify(input, realm.getPublicKey()); - } catch (Exception ignored) { - logger.debug("Failed to verify signature", ignored); - } - if (!verifiedCode) { - return oauth.forwardToSecurityFailure("Illegal access code."); - } - String key = input.readContent(String.class); - AccessCodeEntry accessCodeEntry = tokenManager.getAccessCode(key); - if (accessCodeEntry == null) { - return oauth.forwardToSecurityFailure("Unknown access code."); - } + String code = formData.getFirst("code"); + JWSInput input = new JWSInput(code, providers); + boolean verifiedCode = false; + try { + verifiedCode = RSAProvider.verify(input, realm.getPublicKey()); + } catch (Exception ignored) { + logger.debug("Failed to verify signature", ignored); + } + if (!verifiedCode) { + return oauth.forwardToSecurityFailure("Illegal access code."); + } + String key = input.readContent(String.class); + AccessCodeEntry accessCodeEntry = tokenManager.getAccessCode(key); + if (accessCodeEntry == null) { + return oauth.forwardToSecurityFailure("Unknown access code."); + } - String redirect = accessCodeEntry.getRedirectUri(); - String state = accessCodeEntry.getState(); + String redirect = accessCodeEntry.getRedirectUri(); + String state = accessCodeEntry.getState(); - if (formData.containsKey("cancel")) { - return redirectAccessDenied(redirect, state); - } + if (formData.containsKey("cancel")) { + return redirectAccessDenied(redirect, state); + } - return oauth.redirectAccessCode(accessCodeEntry, state, redirect); - } - }.call(); + return oauth.redirectAccessCode(accessCodeEntry, state, redirect); } protected Response redirectAccessDenied(String redirect, String state) { diff --git a/services/src/main/java/org/keycloak/services/resources/Transaction.java b/services/src/main/java/org/keycloak/services/resources/Transaction.java index d88cc050b7..69188420bb 100755 --- a/services/src/main/java/org/keycloak/services/resources/Transaction.java +++ b/services/src/main/java/org/keycloak/services/resources/Transaction.java @@ -2,17 +2,15 @@ package org.keycloak.services.resources; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.services.models.KeycloakSession; -import org.keycloak.services.models.KeycloakSessionFactory; import org.keycloak.services.models.KeycloakTransaction; -import javax.ws.rs.core.Application; - /** * Meant to be used as an inner class wrapper (I forget the pattern name, its been awhile). * * @author Bill Burke * @version $Revision: 1 $ */ +@Deprecated public class Transaction { protected KeycloakSession session; protected KeycloakTransaction transaction; @@ -36,6 +34,8 @@ public class Transaction { */ public Transaction(boolean close) { this.session = ResteasyProviderFactory.getContextData(KeycloakSession.class); + this.transaction = session.getTransaction(); + /* if (session == null) { KeycloakApplication app = (KeycloakApplication)ResteasyProviderFactory.getContextData(Application.class); session = app.getFactory().createSession(); @@ -44,20 +44,10 @@ public class Transaction { } transaction = session.getTransaction(); closeSession = close; + */ } - /** - * Creates and manages its own session. - * - * @param factory - */ - public Transaction(KeycloakSessionFactory factory) { - this.closeSession = true; - this.session = factory.createSession(); - this.transaction = session.getTransaction(); - } - protected void runImpl() { } @@ -67,20 +57,20 @@ public class Transaction { * */ public void run() { - boolean wasActive = transaction.isActive(); - if (!wasActive) transaction.begin(); - try { +// boolean wasActive = transaction.isActive(); +// if (!wasActive) transaction.begin(); +// try { runImpl(); - if (!wasActive && transaction.isActive()) transaction.commit(); - } catch (RuntimeException e) { - if (!wasActive && transaction.isActive()) transaction.rollback(); - if (created) closeSession = true; - throw e; - } finally { - if (!wasActive && closeSession) { - session.close(); - } - } +// if (!wasActive && transaction.isActive()) transaction.commit(); +// } catch (RuntimeException e) { +// if (!wasActive && transaction.isActive()) transaction.rollback(); +// if (created) closeSession = true; +// throw e; +// } finally { +// if (!wasActive && closeSession) { +// session.close(); +// } +// } } protected T callImpl() { @@ -92,18 +82,18 @@ public class Transaction { * */ public T call() { - boolean wasActive = transaction.isActive(); - if (!wasActive) transaction.begin(); - try { +// boolean wasActive = transaction.isActive(); +// if (!wasActive) transaction.begin(); +// try { T rtn = callImpl(); - if (!wasActive && transaction.isActive()) transaction.commit(); +// if (!wasActive && transaction.isActive()) transaction.commit(); return rtn; - } catch (RuntimeException e) { - if (!wasActive && transaction.isActive()) transaction.rollback(); - if (created) closeSession = true; // close if there was a failure - throw e; - } finally { - if (!wasActive && closeSession) session.close(); - } +// } catch (RuntimeException e) { +// if (!wasActive && transaction.isActive()) transaction.rollback(); +// if (created) closeSession = true; // close if there was a failure +// throw e; +// } finally { +// if (!wasActive && closeSession) session.close(); +// } } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java index 36540ac1b1..191fb240e6 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java @@ -5,16 +5,13 @@ import org.jboss.resteasy.logging.Logger; import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.ResourceManager; -import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.ApplicationModel; +import org.keycloak.services.models.KeycloakSession; +import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.UserModel; -import org.keycloak.services.resources.Transaction; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.PUT; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; /** @@ -27,6 +24,9 @@ public class ApplicationResource { protected RealmModel realm; protected ApplicationModel applicationModel; + @Context + protected KeycloakSession session; + public ApplicationResource(UserModel admin, RealmModel realm, ApplicationModel applicationModel) { this.admin = admin; this.realm = realm; @@ -36,13 +36,8 @@ public class ApplicationResource { @PUT @Consumes(MediaType.APPLICATION_JSON) public void update(final ApplicationRepresentation rep) { - new Transaction() { - @Override - protected void runImpl() { - ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); - resourceManager.updateResource(rep, applicationModel); - } - }.run(); + ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); + resourceManager.updateResource(rep, applicationModel); } @@ -50,12 +45,7 @@ public class ApplicationResource { @NoCache @Produces(MediaType.APPLICATION_JSON) public ApplicationRepresentation getResource(final @PathParam("id") String id) { - return new Transaction() { - @Override - protected ApplicationRepresentation callImpl() { - ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); - return resourceManager.toRepresentation(applicationModel); - } - }.call(); + ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); + return resourceManager.toRepresentation(applicationModel); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java index 9be8bbdc7e..549c4c1b67 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java @@ -5,18 +5,13 @@ import org.jboss.resteasy.logging.Logger; import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.ResourceManager; -import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.ApplicationModel; +import org.keycloak.services.models.KeycloakSession; +import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.UserModel; -import org.keycloak.services.resources.Transaction; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.NotFoundException; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; +import javax.ws.rs.*; +import javax.ws.rs.container.ResourceContext; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -33,6 +28,12 @@ public class ApplicationsResource { protected UserModel admin; protected RealmModel realm; + @Context + protected ResourceContext resourceContext; + + @Context + protected KeycloakSession session; + public ApplicationsResource(UserModel admin, RealmModel realm) { this.admin = admin; this.realm = realm; @@ -42,46 +43,32 @@ public class ApplicationsResource { @Produces(MediaType.APPLICATION_JSON) @NoCache public List getResources() { - return new Transaction>() { - @Override - protected List callImpl() { - List rep = new ArrayList(); - List applicationModels = realm.getApplications(); - ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); - for (ApplicationModel applicationModel : applicationModels) { - rep.add(resourceManager.toRepresentation(applicationModel)); - } - return rep; - } - }.call(); + List rep = new ArrayList(); + List applicationModels = realm.getApplications(); + ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); + for (ApplicationModel applicationModel : applicationModels) { + rep.add(resourceManager.toRepresentation(applicationModel)); + } + return rep; } @POST @Consumes(MediaType.APPLICATION_JSON) public Response createResource(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) { - return new Transaction() { - @Override - protected Response callImpl() { - ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); - ApplicationModel applicationModel = resourceManager.createResource(realm, rep); - return Response.created(uriInfo.getAbsolutePathBuilder().path(applicationModel.getId()).build()).build(); - } - }.call(); + ResourceManager resourceManager = new ResourceManager(new RealmManager(session)); + ApplicationModel applicationModel = resourceManager.createResource(realm, rep); + return Response.created(uriInfo.getAbsolutePathBuilder().path(applicationModel.getId()).build()).build(); } @Path("{id}") public ApplicationResource getResource(final @PathParam("id") String id) { - return new Transaction(false) { - @Override - protected ApplicationResource callImpl() { - ApplicationModel applicationModel = realm.getApplicationById(id); - if (applicationModel == null) { - throw new NotFoundException(); - } - return new ApplicationResource(admin, realm, applicationModel); - } - }.call(); - + ApplicationModel applicationModel = realm.getApplicationById(id); + if (applicationModel == null) { + throw new NotFoundException(); + } + ApplicationResource applicationResource = new ApplicationResource(admin, realm, applicationModel); + resourceContext.initResource(applicationResource); + return applicationResource; } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java index c8309cbd1e..5ed6520407 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -6,20 +6,13 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.managers.RealmManager; +import org.keycloak.services.models.KeycloakSession; import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.RoleModel; import org.keycloak.services.models.UserModel; -import org.keycloak.services.resources.Transaction; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.InternalServerErrorException; -import javax.ws.rs.NotFoundException; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; +import javax.ws.rs.*; +import javax.ws.rs.container.ResourceContext; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; @@ -35,6 +28,12 @@ public class RealmAdminResource { protected UserModel admin; protected RealmModel realm; + @Context + protected ResourceContext resourceContext; + + @Context + protected KeycloakSession session; + public RealmAdminResource(UserModel admin, RealmModel realm) { this.admin = admin; this.realm = realm; @@ -42,19 +41,16 @@ public class RealmAdminResource { @Path("applications") public ApplicationsResource getResources() { - return new ApplicationsResource(admin, realm); + ApplicationsResource applicationsResource = new ApplicationsResource(admin, realm); + resourceContext.initResource(applicationsResource); + return applicationsResource; } @GET @NoCache @Produces("application/json") public RealmRepresentation getRealm() { - return new Transaction() { - @Override - protected RealmRepresentation callImpl() { - return new RealmManager(session).toRepresentation(realm); - } - }.call(); + return new RealmManager(session).toRepresentation(realm); } @@ -63,31 +59,20 @@ public class RealmAdminResource { @NoCache @Produces("application/json") public List getRoles() { - return new Transaction>() { - @Override - protected List callImpl() { - List roleModels = realm.getRoles(); - List roles = new ArrayList(); - for (RoleModel roleModel : roleModels) { - RoleRepresentation role = new RoleRepresentation(roleModel.getName(), roleModel.getDescription()); - roles.add(role); - } - return roles; - } - }.call(); + List roleModels = realm.getRoles(); + List roles = new ArrayList(); + for (RoleModel roleModel : roleModels) { + RoleRepresentation role = new RoleRepresentation(roleModel.getName(), roleModel.getDescription()); + roles.add(role); + } + return roles; } @PUT @Consumes("application/json") public void updateRealm(final RealmRepresentation rep) { - new Transaction() { - @Override - protected void runImpl() { - logger.info("updating realm: " + rep.getRealm()); - new RealmManager(session).updateRealm(rep, realm); - } - }.run(); - + logger.info("updating realm: " + rep.getRealm()); + new RealmManager(session).updateRealm(rep, realm); } @Path("roles/{id}") @@ -95,18 +80,13 @@ public class RealmAdminResource { @NoCache @Produces("application/json") public RoleRepresentation getRole(final @PathParam("id") String id) { - return new Transaction() { - @Override - protected RoleRepresentation callImpl() { - RoleModel roleModel = realm.getRoleById(id); - if (roleModel == null) { - throw new NotFoundException(); - } - RoleRepresentation rep = new RoleRepresentation(roleModel.getName(), roleModel.getDescription()); - rep.setId(roleModel.getId()); - return rep; - } - }.call(); + RoleModel roleModel = realm.getRoleById(id); + if (roleModel == null) { + throw new NotFoundException(); + } + RoleRepresentation rep = new RoleRepresentation(roleModel.getName(), roleModel.getDescription()); + rep.setId(roleModel.getId()); + return rep; } @@ -114,39 +94,27 @@ public class RealmAdminResource { @PUT @Consumes("application/json") public void updateRole(final @PathParam("id") String id, final RoleRepresentation rep) { - new Transaction() { - @Override - protected void runImpl() { - RoleModel role = realm.getRoleById(id); - if (role == null) { - throw new NotFoundException(); - } - role.setName(rep.getName()); - role.setDescription(rep.getDescription()); - } - }.run(); - + RoleModel role = realm.getRoleById(id); + if (role == null) { + throw new NotFoundException(); + } + role.setName(rep.getName()); + role.setDescription(rep.getDescription()); } @Path("roles") @POST @Consumes("application/json") public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) { - return new Transaction() { - @Override - protected Response callImpl() { - if (realm.getRole(rep.getName()) != null) { - throw new InternalServerErrorException(); // todo appropriate status here. - } - RoleModel role = realm.addRole(rep.getName()); - if (role == null) { - throw new NotFoundException(); - } - role.setDescription(rep.getDescription()); - return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build(); - } - }.call(); - + if (realm.getRole(rep.getName()) != null) { + throw new InternalServerErrorException(); // todo appropriate status here. + } + RoleModel role = realm.addRole(rep.getName()); + if (role == null) { + throw new NotFoundException(); + } + role.setDescription(rep.getDescription()); + return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build(); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java index 1082f69a04..dc3b5124dd 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java @@ -4,34 +4,17 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.logging.Logger; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.RealmManager; +import org.keycloak.services.models.KeycloakSession; import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.UserModel; -import org.keycloak.services.resources.PublicRealmResource; import org.keycloak.services.resources.SaasService; -import org.keycloak.services.resources.Transaction; -import javax.ws.rs.Consumes; -import javax.ws.rs.ForbiddenException; -import javax.ws.rs.GET; -import javax.ws.rs.NotAuthorizedException; -import javax.ws.rs.NotFoundException; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.CacheControl; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.GenericEntity; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriBuilder; -import javax.ws.rs.core.UriInfo; +import javax.ws.rs.*; +import javax.ws.rs.container.ResourceContext; +import javax.ws.rs.core.*; import java.net.URI; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** * @author Bill Burke @@ -50,23 +33,24 @@ public class RealmsAdminResource { noCache.setNoCache(true); } + @Context + protected ResourceContext resourceContext; + + @Context + protected KeycloakSession session; + @GET @NoCache @Produces("application/json") public List getRealms() { - return new Transaction>() { - @Override - protected List callImpl() { - logger.info(("getRealms()")); - RealmManager realmManager = new RealmManager(session); - List realms = session.getRealms(admin); - List reps = new ArrayList(); - for (RealmModel realm : realms) { - reps.add(realmManager.toRepresentation(realm)); - } - return reps; - } - }.call(); + logger.info(("getRealms()")); + RealmManager realmManager = new RealmManager(session); + List realms = session.getRealms(admin); + List reps = new ArrayList(); + for (RealmModel realm : realms) { + reps.add(realmManager.toRepresentation(realm)); + } + return reps; } public static UriBuilder realmUrl(UriInfo uriInfo) { @@ -81,34 +65,26 @@ public class RealmsAdminResource { @Consumes("application/json") public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) { logger.info("importRealm: " + rep.getRealm()); - return new Transaction() { - @Override - protected Response callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.importRealm(rep, admin); - URI location = realmUrl(uriInfo).build(realm.getId()); - logger.info("imported realm success, sending back: " + location.toString()); - return Response.created(location).build(); - } - }.call(); + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.importRealm(rep, admin); + URI location = realmUrl(uriInfo).build(realm.getId()); + logger.info("imported realm success, sending back: " + location.toString()); + return Response.created(location).build(); } @Path("{id}") public RealmAdminResource getRealmAdmin(@Context final HttpHeaders headers, @PathParam("id") final String id) { - return new Transaction(false) { - @Override - protected RealmAdminResource callImpl() { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.getRealm(id); - if (realm == null) throw new NotFoundException(); - if (!realm.isRealmAdmin(admin)) { - throw new ForbiddenException(); - } + RealmManager realmManager = new RealmManager(session); + RealmModel realm = realmManager.getRealm(id); + if (realm == null) throw new NotFoundException(); + if (!realm.isRealmAdmin(admin)) { + throw new ForbiddenException(); + } - return new RealmAdminResource(admin, realm); - } - }.call(); + RealmAdminResource adminResource = new RealmAdminResource(admin, realm); + resourceContext.initResource(adminResource); + return adminResource; } diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Flows.java b/services/src/main/java/org/keycloak/services/resources/flows/Flows.java old mode 100644 new mode 100755 index 723d023567..e7ad5894b7 --- a/services/src/main/java/org/keycloak/services/resources/flows/Flows.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/Flows.java @@ -21,13 +21,13 @@ */ package org.keycloak.services.resources.flows; -import javax.ws.rs.core.UriInfo; - import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.TokenManager; import org.keycloak.services.models.RealmModel; +import javax.ws.rs.core.UriInfo; + /** * @author Stian Thorgersen */ diff --git a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java old mode 100644 new mode 100755 index 3804b44b0f..49590fd67c --- a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java @@ -21,14 +21,14 @@ */ package org.keycloak.services.resources.flows; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; - import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.UserModel; import org.picketlink.idm.model.sample.Realm; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + /** * @author Stian Thorgersen */ diff --git a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java old mode 100644 new mode 100755 index 6a87ead696..da18de5405 --- a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java @@ -21,10 +21,6 @@ */ package org.keycloak.services.resources.flows; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriBuilder; -import javax.ws.rs.core.UriInfo; - import org.jboss.resteasy.logging.Logger; import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.services.managers.AccessCodeEntry; @@ -36,6 +32,10 @@ import org.keycloak.services.models.RoleModel; import org.keycloak.services.models.UserModel; import org.keycloak.services.resources.TokenService; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; + /** * @author Bill Burke * @author Stian Thorgersen diff --git a/services/src/main/java/org/keycloak/services/resources/flows/PageFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/PageFlows.java old mode 100644 new mode 100755 index 9b38098f59..dd6edb812d --- a/services/src/main/java/org/keycloak/services/resources/flows/PageFlows.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/PageFlows.java @@ -21,12 +21,12 @@ */ package org.keycloak.services.resources.flows; -import javax.ws.rs.core.Response; - import org.jboss.resteasy.logging.Logger; import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.services.JspRequestParameters; +import javax.ws.rs.core.Response; + /** * @author Stian Thorgersen */ diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java old mode 100644 new mode 100755 index 57fc5fbe5b..a380041546 --- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java @@ -21,15 +21,10 @@ */ package org.keycloak.services.resources.flows; -import java.net.URI; +import org.keycloak.services.resources.*; import javax.ws.rs.core.UriBuilder; - -import org.keycloak.services.resources.AccountService; -import org.keycloak.services.resources.RealmsResource; -import org.keycloak.services.resources.SaasService; -import org.keycloak.services.resources.SocialResource; -import org.keycloak.services.resources.TokenService; +import java.net.URI; /** * @author Stian Thorgersen diff --git a/services/src/main/java/org/keycloak/services/validation/Validation.java b/services/src/main/java/org/keycloak/services/validation/Validation.java old mode 100644 new mode 100755 index f8d85bc42d..58b0650ab6 --- a/services/src/main/java/org/keycloak/services/validation/Validation.java +++ b/services/src/main/java/org/keycloak/services/validation/Validation.java @@ -1,12 +1,11 @@ package org.keycloak.services.validation; -import java.util.List; - -import javax.ws.rs.core.MultivaluedMap; - import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.services.messages.Messages; +import javax.ws.rs.core.MultivaluedMap; +import java.util.List; + public class Validation { public static String validateRegistrationForm(MultivaluedMap formData, List requiredCredentialTypes) { diff --git a/services/src/test/java/org/keycloak/test/AbstractKeycloakServerTest.java b/services/src/test/java/org/keycloak/test/AbstractKeycloakServerTest.java new file mode 100755 index 0000000000..a2b00e14a4 --- /dev/null +++ b/services/src/test/java/org/keycloak/test/AbstractKeycloakServerTest.java @@ -0,0 +1,70 @@ +package org.keycloak.test; + +import io.undertow.servlet.Servlets; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.FilterInfo; +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; +import org.jboss.resteasy.jwt.JsonSerialization; +import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer; +import org.jboss.resteasy.spi.ResteasyDeployment; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.keycloak.SkeletonKeyContextResolver; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.services.filters.KeycloakSessionServletFilter; +import org.keycloak.services.resources.KeycloakApplication; + +import javax.servlet.DispatcherType; +import javax.ws.rs.client.Client; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class AbstractKeycloakServerTest { + public static UndertowJaxrsServer server; + public static ResteasyDeployment deployment; + public static Client client; + public static KeycloakApplication application; + + @BeforeClass + public static void undertowSetup() throws Exception { + deployment = new ResteasyDeployment(); + deployment.setApplicationClass(KeycloakApplication.class.getName()); + server = new UndertowJaxrsServer().start(); + DeploymentInfo di = server.undertowDeployment(deployment); + di.setClassLoader(AbstractKeycloakServerTest.class.getClassLoader()); + di.setContextPath("/"); + di.setDeploymentName("Keycloak"); + + FilterInfo filter = Servlets.filter("SessionFilter", KeycloakSessionServletFilter.class); + di.addFilter(filter); + di.addFilterUrlMapping("SessionFilter", "/*", DispatcherType.REQUEST); + server.deploy(di); + application = (KeycloakApplication) deployment.getApplication(); + client = new ResteasyClientBuilder().connectionPoolSize(10).build(); + client.register(SkeletonKeyContextResolver.class); + + } + + @AfterClass + public static void undertowShutdown() throws Exception { + server.stop(); + } + + public static RealmRepresentation loadJson(String path) throws IOException { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + int c; + while ((c = is.read()) != -1) { + os.write(c); + } + byte[] bytes = os.toByteArray(); + System.out.println(new String(bytes)); + + return JsonSerialization.fromBytes(RealmRepresentation.class, bytes); + } +} diff --git a/services/src/test/java/org/keycloak/test/ImportTest.java b/services/src/test/java/org/keycloak/test/ImportTest.java index 68cd9edb9a..1e67cd4824 100755 --- a/services/src/test/java/org/keycloak/test/ImportTest.java +++ b/services/src/test/java/org/keycloak/test/ImportTest.java @@ -64,7 +64,7 @@ public class ImportTest { UserModel admin = defaultRealm.addUser("admin"); defaultRealm.grantRole(admin, role); - RealmRepresentation rep = KeycloakTestBase.loadJson("testrealm.json"); + RealmRepresentation rep = AbstractKeycloakServerTest.loadJson("testrealm.json"); RealmModel realm = manager.createRealm("demo", rep.getRealm()); manager.importRealm(rep, realm); realm.addRealmAdmin(admin); @@ -112,7 +112,7 @@ public class ImportTest { UserModel admin = defaultRealm.addUser("admin"); defaultRealm.grantRole(admin, role); - RealmRepresentation rep = KeycloakTestBase.loadJson("testrealm-demo.json"); + RealmRepresentation rep = AbstractKeycloakServerTest.loadJson("testrealm-demo.json"); RealmModel realm = manager.createRealm("demo", rep.getRealm()); manager.importRealm(rep, realm); realm.addRealmAdmin(admin); diff --git a/services/src/test/java/org/keycloak/test/KeycloakTestBase.java b/services/src/test/java/org/keycloak/test/KeycloakTestBase.java deleted file mode 100755 index 5bd0b6da7a..0000000000 --- a/services/src/test/java/org/keycloak/test/KeycloakTestBase.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.keycloak.test; - -import org.jboss.resteasy.jwt.JsonSerialization; -import org.jboss.resteasy.test.BaseResourceTest; -import org.keycloak.representations.idm.RealmRepresentation; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class KeycloakTestBase extends BaseResourceTest -{ - public static RealmRepresentation loadJson(String path) throws IOException - { - InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - int c; - while ( (c = is.read()) != -1) - { - os.write(c); - } - byte[] bytes = os.toByteArray(); - System.out.println(new String(bytes)); - - return JsonSerialization.fromBytes(RealmRepresentation.class, bytes); - } -} diff --git a/services/src/test/java/org/keycloak/test/RealmCreationTest.java b/services/src/test/java/org/keycloak/test/RealmCreationTest.java index 0d446ff2f6..c93c7429ab 100755 --- a/services/src/test/java/org/keycloak/test/RealmCreationTest.java +++ b/services/src/test/java/org/keycloak/test/RealmCreationTest.java @@ -1,12 +1,8 @@ package org.keycloak.test; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.spi.ResteasyDeployment; -import org.jboss.resteasy.test.EmbeddedContainer; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.keycloak.SkeletonKeyContextResolver; import org.keycloak.representations.AccessTokenResponse; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.RealmRepresentation; @@ -15,10 +11,8 @@ import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.models.KeycloakSession; import org.keycloak.services.models.RealmModel; -import org.keycloak.services.resources.KeycloakApplication; import javax.ws.rs.NotAuthorizedException; -import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Form; @@ -31,30 +25,16 @@ import static org.jboss.resteasy.test.TestPortProvider.generateURL; * @author Bill Burke * @version $Revision: 1 $ */ -public class RealmCreationTest { - - private static ResteasyDeployment deployment; - private static Client client; +public class RealmCreationTest extends AbstractKeycloakServerTest { @BeforeClass public static void before() throws Exception { - deployment = new ResteasyDeployment(); - deployment.setApplicationClass(KeycloakApplication.class.getName()); - EmbeddedContainer.start(deployment); - KeycloakApplication application = (KeycloakApplication) deployment.getApplication(); KeycloakSession session = application.getFactory().createSession(); session.getTransaction().begin(); RealmManager manager = new RealmManager(session); new InstallationManager().install(manager); session.getTransaction().commit(); session.close(); - client = new ResteasyClientBuilder().build(); - client.register(SkeletonKeyContextResolver.class); - } - - public static void after() throws Exception { - client.close(); - EmbeddedContainer.stop(); } @Test @@ -86,7 +66,7 @@ public class RealmCreationTest { System.out.println(tokenResponse.getToken()); // - RealmRepresentation realm = KeycloakTestBase.loadJson("testrealm.json"); + RealmRepresentation realm = loadJson("testrealm.json"); response = target.path("saas/admin/realms").request().header(HttpHeaders.AUTHORIZATION, "Bearer " + tokenResponse.getToken()).post(Entity.json(realm)); Assert.assertEquals(201, response.getStatus()); response.close();