diff --git a/common/src/main/java/org/keycloak/common/util/ConcurrentMultivaluedHashMap.java b/common/src/main/java/org/keycloak/common/util/ConcurrentMultivaluedHashMap.java deleted file mode 100755 index 56226e0241..0000000000 --- a/common/src/main/java/org/keycloak/common/util/ConcurrentMultivaluedHashMap.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.common.util; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -@SuppressWarnings("serial") -public class ConcurrentMultivaluedHashMap extends ConcurrentHashMap> -{ - public void putSingle(K key, V value) - { - List list = new CopyOnWriteArrayList<>(); - list.add(value); - put(key, list); - } - - public void addAll(K key, V... newValues) - { - for (V value : newValues) - { - add(key, value); - } - } - - public void addAll(K key, List valueList) - { - for (V value : valueList) - { - add(key, value); - } - } - - public void addFirst(K key, V value) - { - List list = get(key); - if (list == null) - { - add(key, value); - } - else - { - list.add(0, value); - } - } - public final void add(K key, V value) - { - getList(key).add(value); - } - - - public final void addMultiple(K key, Collection values) - { - getList(key).addAll(values); - } - - public V getFirst(K key) - { - List list = get(key); - return list == null ? null : list.get(0); - } - - public final List getList(K key) - { - List list = get(key); - if (list == null) - put(key, list = new CopyOnWriteArrayList()); - return list; - } - - public void addAll(ConcurrentMultivaluedHashMap other) - { - for (Entry> entry : other.entrySet()) - { - getList(entry.getKey()).addAll(entry.getValue()); - } - } - -} diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml index 94c80a2a96..5373067447 100755 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml @@ -25,7 +25,6 @@ - diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-spi/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-spi/main/module.xml index 8b5632e30a..95f34b6943 100755 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-spi/main/module.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-spi/main/module.xml @@ -33,6 +33,5 @@ - diff --git a/federation/ldap/pom.xml b/federation/ldap/pom.xml index 257c617af0..f6a8c4bae1 100755 --- a/federation/ldap/pom.xml +++ b/federation/ldap/pom.xml @@ -74,11 +74,6 @@ junit test - - org.jboss.spec.javax.transaction - jboss-transaction-api_1.2_spec - provided - diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanUserCacheProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java similarity index 79% rename from model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanUserCacheProviderFactory.java rename to model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java index c5205381bf..e0409b1aa5 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanUserCacheProviderFactory.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java @@ -18,28 +18,34 @@ package org.keycloak.models.cache.infinispan; import org.infinispan.Cache; +import org.infinispan.notifications.Listener; +import org.infinispan.notifications.cachelistener.annotation.*; +import org.infinispan.notifications.cachelistener.event.*; import org.jboss.logging.Logger; import org.keycloak.Config; import org.keycloak.connections.infinispan.InfinispanConnectionProvider; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.models.cache.UserCache; -import org.keycloak.models.cache.UserCacheProviderFactory; +import org.keycloak.models.cache.CacheUserProvider; +import org.keycloak.models.cache.CacheUserProviderFactory; +import org.keycloak.models.cache.infinispan.entities.CachedUser; import org.keycloak.models.cache.infinispan.entities.Revisioned; +import java.util.concurrent.ConcurrentHashMap; + /** * @author Stian Thorgersen */ -public class InfinispanUserCacheProviderFactory implements UserCacheProviderFactory { +public class InfinispanCacheUserProviderFactory implements CacheUserProviderFactory { - private static final Logger log = Logger.getLogger(InfinispanUserCacheProviderFactory.class); + private static final Logger log = Logger.getLogger(InfinispanCacheUserProviderFactory.class); protected volatile UserCacheManager userCache; @Override - public UserCache create(KeycloakSession session) { + public CacheUserProvider create(KeycloakSession session) { lazyInit(session); return new UserCacheSession(userCache, session); } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java index ea6698cf83..d697ad236e 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java @@ -28,7 +28,6 @@ import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialValueModel; import org.keycloak.models.UserModel; -import org.keycloak.models.cache.CachedUserModel; import org.keycloak.models.cache.infinispan.entities.CachedUser; import org.keycloak.models.cache.infinispan.entities.CachedUserConsent; import org.keycloak.models.utils.KeycloakModelUtils; @@ -40,13 +39,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; /** * @author Bill Burke * @version $Revision: 1 $ */ -public class UserAdapter implements CachedUserModel { +public class UserAdapter implements UserModel { protected UserModel updated; protected CachedUser cached; protected UserCacheSession userProviderCache; @@ -67,22 +65,6 @@ public class UserAdapter implements CachedUserModel { if (updated == null) throw new IllegalStateException("Not found in database"); } } - - @Override - public void invalidate() { - getDelegateForUpdate(); - } - - @Override - public long getCacheTimestamp() { - return cached.getCacheTimestamp(); - } - - @Override - public ConcurrentHashMap getCachedWith() { - return cached.getCachedWith(); - } - @Override public String getId() { if (updated != null) return updated.getId(); diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java index b38d9aab1b..8a62c3337e 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java @@ -34,9 +34,7 @@ import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; -import org.keycloak.models.cache.CachedUserModel; -import org.keycloak.models.cache.OnUserCache; -import org.keycloak.models.cache.UserCache; +import org.keycloak.models.cache.CacheUserProvider; import org.keycloak.models.cache.infinispan.entities.CachedFederatedIdentityLinks; import org.keycloak.models.cache.infinispan.entities.CachedUser; import org.keycloak.models.cache.infinispan.entities.CachedUserConsent; @@ -49,7 +47,7 @@ import java.util.*; * @author Bill Burke * @version $Revision: 1 $ */ -public class UserCacheSession implements UserCache { +public class UserCacheSession implements CacheUserProvider { protected static final Logger logger = Logger.getLogger(UserCacheSession.class); protected UserCacheManager cache; protected KeycloakSession session; @@ -75,6 +73,7 @@ public class UserCacheSession implements UserCache { cache.clear(); } + @Override public UserProvider getDelegate() { if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction"); if (delegate != null) return delegate; @@ -90,20 +89,6 @@ public class UserCacheSession implements UserCache { if (realm.isIdentityFederationEnabled()) invalidations.add(getFederatedIdentityLinksCacheKey(user.getId())); } - @Override - public void evict(RealmModel realm, UserModel user) { - if (user instanceof CachedUserModel) { - ((CachedUserModel)user).invalidate(); - } else { - invalidations.add(user.getId()); - if (user.getEmail() != null) invalidations.add(getUserByEmailCacheKey(realm.getId(), user.getEmail())); - invalidations.add(getUserByUsernameCacheKey(realm.getId(), user.getUsername())); - if (realm.isIdentityFederationEnabled()) invalidations.add(getFederatedIdentityLinksCacheKey(user.getId())); - } - } - - - protected void runInvalidations() { for (String realmId : realmInvalidations) { cache.invalidateRealmUsers(realmId, invalidations); @@ -162,13 +147,8 @@ public class UserCacheSession implements UserCache { logger.trace("registered for invalidation return delegate"); return getDelegate().getUserById(id, realm); } - if (managedUsers.containsKey(id)) { - logger.trace("return managedusers"); - return managedUsers.get(id); - } CachedUser cached = cache.get(id, CachedUser.class); - boolean wasCached = cached != null; if (cached == null) { logger.trace("not cached"); Long loaded = cache.getCurrentRevision(id); @@ -177,12 +157,19 @@ public class UserCacheSession implements UserCache { logger.trace("delegate returning null"); return null; } + if (managedUsers.containsKey(id)) { + logger.trace("return managedusers"); + return managedUsers.get(id); + } + if (invalidations.contains(id)) return model; cached = new CachedUser(loaded, realm, model); cache.addRevisioned(cached, startupRevision); + } else if (managedUsers.containsKey(id)) { + logger.trace("return managedusers"); + return managedUsers.get(id); } logger.trace("returning new cache adapter"); UserAdapter adapter = new UserAdapter(cached, this, session, realm); - if (!wasCached) onCache(realm, adapter); managedUsers.put(id, adapter); return adapter; } @@ -236,7 +223,13 @@ public class UserCacheSession implements UserCache { return managedUsers.get(userId); } - UserAdapter adapter = getUserAdapter(realm, userId, loaded, model); + CachedUser cached = cache.get(userId, CachedUser.class); + if (cached == null) { + cached = new CachedUser(loaded, realm, model); + cache.addRevisioned(cached, startupRevision); + } + logger.trace("return new cache adapter"); + UserAdapter adapter = new UserAdapter(cached, this, session, realm); managedUsers.put(userId, adapter); return adapter; } else { @@ -251,26 +244,6 @@ public class UserCacheSession implements UserCache { } } - protected UserAdapter getUserAdapter(RealmModel realm, String userId, Long loaded, UserModel model) { - CachedUser cached = cache.get(userId, CachedUser.class); - boolean wasCached = cached != null; - if (cached == null) { - cached = new CachedUser(loaded, realm, model); - cache.addRevisioned(cached, startupRevision); - } - UserAdapter adapter = new UserAdapter(cached, this, session, realm); - if (!wasCached) { - onCache(realm, adapter); - } - return adapter; - - } - - private void onCache(RealmModel realm, UserAdapter adapter) { - ((OnUserCache)getDelegate()).onCache(realm, adapter); - ((OnUserCache)session.userCredentialManager()).onCache(realm, adapter); - } - @Override public UserModel getUserByEmail(String email, RealmModel realm) { if (email == null) return null; @@ -295,7 +268,12 @@ public class UserCacheSession implements UserCache { if (invalidations.contains(userId)) return model; if (managedUsers.containsKey(userId)) return managedUsers.get(userId); - UserAdapter adapter = getUserAdapter(realm, userId, loaded, model); + CachedUser cached = cache.get(userId, CachedUser.class); + if (cached == null) { + cached = new CachedUser(loaded, realm, model); + cache.addRevisioned(cached, startupRevision); + } + UserAdapter adapter = new UserAdapter(cached, this, session, realm); managedUsers.put(userId, adapter); return adapter; } else { @@ -338,7 +316,12 @@ public class UserCacheSession implements UserCache { if (invalidations.contains(userId)) return model; if (managedUsers.containsKey(userId)) return managedUsers.get(userId); - UserAdapter adapter = getUserAdapter(realm, userId, loaded, model); + CachedUser cached = cache.get(userId, CachedUser.class); + if (cached == null) { + cached = new CachedUser(loaded, realm, model); + cache.addRevisioned(cached, startupRevision); + } + UserAdapter adapter = new UserAdapter(cached, this, session, realm); managedUsers.put(userId, adapter); return adapter; } else { @@ -686,5 +669,4 @@ public class UserCacheSession implements UserCache { getDelegate().preRemove(realm, component); } - } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/AbstractExtendableRevisioned.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/AbstractExtendableRevisioned.java deleted file mode 100644 index 9940732841..0000000000 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/AbstractExtendableRevisioned.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.models.cache.infinispan.entities; - -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public abstract class AbstractExtendableRevisioned extends AbstractRevisioned { - protected ConcurrentHashMap cachedWith = new ConcurrentHashMap(); - - public AbstractExtendableRevisioned(Long revision, String id) { - super(revision, id); - } - - /** - * Cache things along with this cachable object - * - * @return - */ - public ConcurrentHashMap getCachedWith() { - return cachedWith; - } -} diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/AbstractRevisioned.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/AbstractRevisioned.java index ed49ddff1e..89166202c5 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/AbstractRevisioned.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/AbstractRevisioned.java @@ -9,7 +9,6 @@ import java.io.Serializable; public class AbstractRevisioned implements Revisioned, Serializable { private String id; private Long revision; - private final long cacheTimestamp = System.currentTimeMillis(); public AbstractRevisioned(Long revision, String id) { this.revision = revision; @@ -31,12 +30,4 @@ public class AbstractRevisioned implements Revisioned, Serializable { this.revision = revision; } - /** - * When was this cached - * - * @return - */ - public long getCacheTimestamp() { - return cacheTimestamp; - } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java index 7c24594885..89049cae99 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java @@ -36,7 +36,7 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class CachedUser extends AbstractExtendableRevisioned implements InRealm { +public class CachedUser extends AbstractRevisioned implements InRealm { private String realm; private String username; private Long createdTimestamp; diff --git a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.cache.UserCacheProviderFactory b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory similarity index 91% rename from model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.cache.UserCacheProviderFactory rename to model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory index e558cf21e9..f680e3a4c3 100755 --- a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.cache.UserCacheProviderFactory +++ b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory @@ -15,4 +15,4 @@ # limitations under the License. # -org.keycloak.models.cache.infinispan.InfinispanUserCacheProviderFactory \ No newline at end of file +org.keycloak.models.cache.infinispan.InfinispanCacheUserProviderFactory \ No newline at end of file diff --git a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ClusteredCacheBehaviorTest.java b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ClusteredCacheBehaviorTest.java index 4c5ccc47d0..de6e587d0a 100755 --- a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ClusteredCacheBehaviorTest.java +++ b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ClusteredCacheBehaviorTest.java @@ -101,19 +101,14 @@ public class ClusteredCacheBehaviorTest { System.out.println("node1 create entry"); node1Cache.put("key", "node1"); - System.out.println("node1 create entry"); node1Cache.put("key", "node111"); - System.out.println("node2 create entry"); node2Cache.put("key", "node2"); - System.out.println("node1 remove entry"); node1Cache.remove("key"); - System.out.println("node2 remove entry"); node2Cache.remove("key"); - System.out.println("node2 put entry"); node2Cache.put("key", "node2"); System.out.println("node2 evict entry"); @@ -123,28 +118,6 @@ public class ClusteredCacheBehaviorTest { node2Cache.putForExternalRead("key", "common"); System.out.println("node2 remove entry"); node2Cache.remove("key"); - System.out.println("node1 remove entry"); - node1Cache.remove("key"); - - // test remove non-existing node 2, existing node 1 - System.out.println("Test non existent remove"); - System.out.println("node1 create entry"); - node1Cache.put("key", "value"); - System.out.println("node2 remove non-existent entry"); - System.out.println("exists?: " + node2Cache.containsKey("key")); - node2Cache.remove("key"); - - // test clear - System.out.println("Test clear cache"); - System.out.println("add key to node 1, key2 to node2"); - node1Cache.putForExternalRead("key", "value"); - node2Cache.putForExternalRead("key", "value"); - node2Cache.putForExternalRead("key2", "value"); - System.out.println("Clear from node1"); - node1Cache.clear(); - System.out.println("node 2 exists key2?: " + node2Cache.containsKey("key2")); - System.out.println("node 2 exists key?: " + node2Cache.containsKey("key")); - } diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProvider.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProvider.java index e35e5b0734..db85a825c9 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProvider.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProvider.java @@ -17,8 +17,6 @@ package org.keycloak.connections.jpa; -import org.jboss.logging.Logger; - import javax.persistence.EntityManager; /** @@ -26,7 +24,6 @@ import javax.persistence.EntityManager; */ public class DefaultJpaConnectionProvider implements JpaConnectionProvider { - private static final Logger logger = Logger.getLogger(DefaultJpaConnectionProvider.class); private final EntityManager em; public DefaultJpaConnectionProvider(EntityManager em) { @@ -40,7 +37,6 @@ public class DefaultJpaConnectionProvider implements JpaConnectionProvider { @Override public void close() { - logger.trace("DefaultJpaConnectionProvider close()"); em.close(); } diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java index d029e16767..3c74264f8d 100755 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java @@ -29,22 +29,12 @@ import java.util.Map; import javax.naming.InitialContext; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; -import javax.persistence.SynchronizationType; import javax.sql.DataSource; -import javax.transaction.InvalidTransactionException; -import javax.transaction.Synchronization; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; -import javax.transaction.UserTransaction; import org.hibernate.ejb.AvailableSettings; -import org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform; -import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; import org.jboss.logging.Logger; import org.keycloak.Config; import org.keycloak.connections.jpa.updater.JpaUpdaterProvider; -import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProvider; import org.keycloak.connections.jpa.util.JpaUtils; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; @@ -55,7 +45,6 @@ import org.keycloak.provider.ServerInfoAwareProviderFactory; import org.keycloak.models.dblock.DBLockManager; import org.keycloak.ServerStartupError; import org.keycloak.timer.TimerProvider; -import org.keycloak.transaction.JtaTransactionManagerLookup; /** * @author Stian Thorgersen @@ -71,29 +60,16 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide private volatile EntityManagerFactory emf; private Config.Scope config; - - private Map operationalInfo; - - private boolean jtaEnabled; - private JtaTransactionManagerLookup jtaLookup; - - private KeycloakSessionFactory factory; + + private Map operationalInfo; @Override public JpaConnectionProvider create(KeycloakSession session) { - logger.trace("Create JpaConnectionProvider"); lazyInit(session); - EntityManager em = null; - if (!jtaEnabled) { - logger.trace("enlisting EntityManager in JpaKeycloakTransaction"); - em = emf.createEntityManager(); - } else { - - em = emf.createEntityManager(SynchronizationType.SYNCHRONIZED); - } + EntityManager em = emf.createEntityManager(); em = PersistenceExceptionConverter.create(em); - if (!jtaEnabled) session.getTransactionManager().enlist(new JpaKeycloakTransaction(em)); + session.getTransactionManager().enlist(new JpaKeycloakTransaction(em)); return new DefaultJpaConnectionProvider(em); } @@ -116,112 +92,85 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide @Override public void postInit(KeycloakSessionFactory factory) { - this.factory = factory; - checkJtaEnabled(factory); } - protected void checkJtaEnabled(KeycloakSessionFactory factory) { - jtaLookup = (JtaTransactionManagerLookup) factory.getProviderFactory(JtaTransactionManagerLookup.class); - if (jtaLookup != null) { - if (jtaLookup.getTransactionManager() != null) { - jtaEnabled = true; - } - } - } - private void lazyInit(KeycloakSession session) { if (emf == null) { synchronized (this) { if (emf == null) { - KeycloakModelUtils.suspendJtaTransaction(session.getKeycloakSessionFactory(), () -> { - logger.debug("Initializing JPA connections"); + logger.debug("Initializing JPA connections"); - Map properties = new HashMap(); + Map properties = new HashMap(); - String unitName = "keycloak-default"; + String unitName = "keycloak-default"; - String dataSource = config.get("dataSource"); - if (dataSource != null) { - if (config.getBoolean("jta", jtaEnabled)) { - properties.put(AvailableSettings.JTA_DATASOURCE, dataSource); - } else { - properties.put(AvailableSettings.NON_JTA_DATASOURCE, dataSource); - } + String dataSource = config.get("dataSource"); + if (dataSource != null) { + if (config.getBoolean("jta", false)) { + properties.put(AvailableSettings.JTA_DATASOURCE, dataSource); } else { - properties.put(AvailableSettings.JDBC_URL, config.get("url")); - properties.put(AvailableSettings.JDBC_DRIVER, config.get("driver")); + properties.put(AvailableSettings.NON_JTA_DATASOURCE, dataSource); + } + } else { + properties.put(AvailableSettings.JDBC_URL, config.get("url")); + properties.put(AvailableSettings.JDBC_DRIVER, config.get("driver")); - String user = config.get("user"); - if (user != null) { - properties.put(AvailableSettings.JDBC_USER, user); - } - String password = config.get("password"); - if (password != null) { - properties.put(AvailableSettings.JDBC_PASSWORD, password); - } + String user = config.get("user"); + if (user != null) { + properties.put(AvailableSettings.JDBC_USER, user); + } + String password = config.get("password"); + if (password != null) { + properties.put(AvailableSettings.JDBC_PASSWORD, password); + } + } + + String schema = getSchema(); + if (schema != null) { + properties.put(JpaUtils.HIBERNATE_DEFAULT_SCHEMA, schema); + } + + MigrationStrategy migrationStrategy = getMigrationStrategy(); + boolean initializeEmpty = config.getBoolean("initializeEmpty", true); + File databaseUpdateFile = getDatabaseUpdateFile(); + + properties.put("hibernate.show_sql", config.getBoolean("showSql", false)); + properties.put("hibernate.format_sql", config.getBoolean("formatSql", true)); + + Connection connection = getConnection(); + try{ + prepareOperationalInfo(connection); + + String driverDialect = detectDialect(connection); + if (driverDialect != null) { + properties.put("hibernate.dialect", driverDialect); } - String schema = getSchema(); - if (schema != null) { - properties.put(JpaUtils.HIBERNATE_DEFAULT_SCHEMA, schema); + migration(migrationStrategy, initializeEmpty, schema, databaseUpdateFile, connection, session); + + int globalStatsInterval = config.getInt("globalStatsInterval", -1); + if (globalStatsInterval != -1) { + properties.put("hibernate.generate_statistics", true); } - MigrationStrategy migrationStrategy = getMigrationStrategy(); - boolean initializeEmpty = config.getBoolean("initializeEmpty", true); - File databaseUpdateFile = getDatabaseUpdateFile(); + logger.trace("Creating EntityManagerFactory"); + emf = JpaUtils.createEntityManagerFactory(session, unitName, properties, getClass().getClassLoader()); + logger.trace("EntityManagerFactory created"); - properties.put("hibernate.show_sql", config.getBoolean("showSql", false)); - properties.put("hibernate.format_sql", config.getBoolean("formatSql", true)); - - Connection connection = getConnection(); - try { - prepareOperationalInfo(connection); - - String driverDialect = detectDialect(connection); - if (driverDialect != null) { - properties.put("hibernate.dialect", driverDialect); - } - - migration(migrationStrategy, initializeEmpty, schema, databaseUpdateFile, connection, session); - - int globalStatsInterval = config.getInt("globalStatsInterval", -1); - if (globalStatsInterval != -1) { - properties.put("hibernate.generate_statistics", true); - } - - logger.trace("Creating EntityManagerFactory"); - logger.tracev("***** create EMF jtaEnabled {0} ", jtaEnabled); - if (jtaEnabled) { - properties.put(org.hibernate.cfg.AvailableSettings.JTA_PLATFORM, new AbstractJtaPlatform() { - @Override - protected TransactionManager locateTransactionManager() { - return jtaLookup.getTransactionManager(); - } - - @Override - protected UserTransaction locateUserTransaction() { - return null; - } - }); - } - emf = JpaUtils.createEntityManagerFactory(session, unitName, properties, getClass().getClassLoader(), jtaEnabled); - logger.trace("EntityManagerFactory created"); - - if (globalStatsInterval != -1) { - startGlobalStats(session, globalStatsInterval); - } - } finally { - // Close after creating EntityManagerFactory to prevent in-mem databases from closing - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - logger.warn("Can't close connection", e); - } - } + if (globalStatsInterval != -1) { + startGlobalStats(session, globalStatsInterval); } - }); + } finally { + // Close after creating EntityManagerFactory to prevent in-mem databases from closing + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + logger.warn("Can't close connection", e); + } + } + } } } } @@ -233,19 +182,19 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide } protected void prepareOperationalInfo(Connection connection) { - try { - operationalInfo = new LinkedHashMap<>(); - DatabaseMetaData md = connection.getMetaData(); - operationalInfo.put("databaseUrl", md.getURL()); - operationalInfo.put("databaseUser", md.getUserName()); - operationalInfo.put("databaseProduct", md.getDatabaseProductName() + " " + md.getDatabaseProductVersion()); - operationalInfo.put("databaseDriver", md.getDriverName() + " " + md.getDriverVersion()); + try { + operationalInfo = new LinkedHashMap<>(); + DatabaseMetaData md = connection.getMetaData(); + operationalInfo.put("databaseUrl",md.getURL()); + operationalInfo.put("databaseUser", md.getUserName()); + operationalInfo.put("databaseProduct", md.getDatabaseProductName() + " " + md.getDatabaseProductVersion()); + operationalInfo.put("databaseDriver", md.getDriverName() + " " + md.getDriverVersion()); logger.debugf("Database info: %s", operationalInfo.toString()); - } catch (SQLException e) { - logger.warn("Unable to prepare operational info due database exception: " + e.getMessage()); - } - } + } catch (SQLException e) { + logger.warn("Unable to prepare operational info due database exception: " + e.getMessage()); + } + } protected String detectDialect(Connection connection) { @@ -385,11 +334,11 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide public String getSchema() { return config.get("schema"); } - + @Override - public Map getOperationalInfo() { - return operationalInfo; - } + public Map getOperationalInfo() { + return operationalInfo; + } private MigrationStrategy getMigrationStrategy() { String migrationStrategy = config.get("migrationStrategy"); diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/lock/LiquibaseDBLockProvider.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/lock/LiquibaseDBLockProvider.java index d080542032..7c48499798 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/lock/LiquibaseDBLockProvider.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/lock/LiquibaseDBLockProvider.java @@ -23,13 +23,14 @@ import java.sql.SQLException; import liquibase.Liquibase; import liquibase.exception.DatabaseException; import liquibase.exception.LiquibaseException; +import liquibase.exception.LockException; +import liquibase.lockservice.LockService; import org.jboss.logging.Logger; import org.keycloak.connections.jpa.JpaConnectionProvider; import org.keycloak.connections.jpa.JpaConnectionProviderFactory; import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProvider; import org.keycloak.models.KeycloakSession; import org.keycloak.models.dblock.DBLockProvider; -import org.keycloak.models.utils.KeycloakModelUtils; /** * @author Marek Posolda @@ -56,7 +57,6 @@ public class LiquibaseDBLockProvider implements DBLockProvider { this.session = session; } - private void lazyInit() { if (!initialized) { LiquibaseConnectionProvider liquibaseProvider = session.getProvider(LiquibaseConnectionProvider.class); @@ -92,41 +92,35 @@ public class LiquibaseDBLockProvider implements DBLockProvider { @Override public void waitForLock() { - KeycloakModelUtils.suspendJtaTransaction(session.getKeycloakSessionFactory(), () -> { + lazyInit(); - lazyInit(); - - while (maxAttempts > 0) { - try { - lockService.waitForLock(); - factory.setHasLock(true); - this.maxAttempts = DEFAULT_MAX_ATTEMPTS; - return; - } catch (LockRetryException le) { - // Indicates we should try to acquire lock again in different transaction - safeRollbackConnection(); - restart(); - maxAttempts--; - } catch (RuntimeException re) { - safeRollbackConnection(); - safeCloseConnection(); - throw re; - } + while (maxAttempts > 0) { + try { + lockService.waitForLock(); + factory.setHasLock(true); + this.maxAttempts = DEFAULT_MAX_ATTEMPTS; + return; + } catch (LockRetryException le) { + // Indicates we should try to acquire lock again in different transaction + safeRollbackConnection(); + restart(); + maxAttempts--; + } catch (RuntimeException re) { + safeRollbackConnection(); + safeCloseConnection(); + throw re; } - }); - + } } @Override public void releaseLock() { - KeycloakModelUtils.suspendJtaTransaction(session.getKeycloakSessionFactory(), () -> { - lazyInit(); + lazyInit(); - lockService.releaseLock(); - lockService.reset(); - factory.setHasLock(false); - }); + lockService.releaseLock(); + lockService.reset(); + factory.setHasLock(false); } @Override @@ -142,25 +136,21 @@ public class LiquibaseDBLockProvider implements DBLockProvider { @Override public void destroyLockInfo() { - KeycloakModelUtils.suspendJtaTransaction(session.getKeycloakSessionFactory(), () -> { - lazyInit(); + lazyInit(); - try { - this.lockService.destroy(); - dbConnection.commit(); - logger.debug("Destroyed lock table"); - } catch (DatabaseException | SQLException de) { - logger.error("Failed to destroy lock table"); - safeRollbackConnection(); - } - }); + try { + this.lockService.destroy(); + dbConnection.commit(); + logger.debug("Destroyed lock table"); + } catch (DatabaseException | SQLException de) { + logger.error("Failed to destroy lock table"); + safeRollbackConnection(); + } } @Override public void close() { - KeycloakModelUtils.suspendJtaTransaction(session.getKeycloakSessionFactory(), () -> { - safeCloseConnection(); - }); + safeCloseConnection(); } private void safeRollbackConnection() { diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java index 0385f6aa70..5ac7d2f6a9 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java @@ -21,8 +21,6 @@ import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl; import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; import org.hibernate.jpa.boot.internal.PersistenceXmlParser; import org.hibernate.jpa.boot.spi.Bootstrap; -import org.jboss.logging.Logger; -import org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory; import org.keycloak.connections.jpa.entityprovider.JpaEntityProvider; import org.keycloak.connections.jpa.entityprovider.ProxyClassLoader; import org.keycloak.models.KeycloakSession; @@ -48,9 +46,8 @@ public class JpaUtils { return (schema==null) ? tableName : schema + "." + tableName; } - public static EntityManagerFactory createEntityManagerFactory(KeycloakSession session, String unitName, Map properties, ClassLoader classLoader, boolean jta) { - PersistenceUnitTransactionType txType = jta ? PersistenceUnitTransactionType.JTA : PersistenceUnitTransactionType.RESOURCE_LOCAL; - PersistenceXmlParser parser = new PersistenceXmlParser(new ClassLoaderServiceImpl(classLoader), txType); + public static EntityManagerFactory createEntityManagerFactory(KeycloakSession session, String unitName, Map properties, ClassLoader classLoader) { + PersistenceXmlParser parser = new PersistenceXmlParser(new ClassLoaderServiceImpl(classLoader), PersistenceUnitTransactionType.RESOURCE_LOCAL); List persistenceUnits = parser.doResolve(properties); for (ParsedPersistenceXmlDescriptor persistenceUnit : persistenceUnits) { if (persistenceUnit.getName().equals(unitName)) { @@ -61,7 +58,6 @@ public class JpaUtils { } // Now build the entity manager factory, supplying a proxy classloader, so Hibernate will be able // to find and load the extra provided entities. Set the provided classloader as parent classloader. - persistenceUnit.setTransactionType(txType); return Bootstrap.getEntityManagerFactoryBuilder(persistenceUnit, properties, new ProxyClassLoader(providedEntities, classLoader)).build(); } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserCredentialStore.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserCredentialStore.java deleted file mode 100644 index d3539fe8d7..0000000000 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserCredentialStore.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.models.jpa; - -import org.keycloak.common.util.MultivaluedHashMap; -import org.keycloak.credential.CredentialModel; -import org.keycloak.credential.UserCredentialStore; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.jpa.entities.CredentialAttributeEntity; -import org.keycloak.models.jpa.entities.CredentialEntity; -import org.keycloak.models.jpa.entities.UserEntity; -import org.keycloak.models.utils.KeycloakModelUtils; - -import javax.persistence.EntityManager; -import javax.persistence.TypedQuery; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class JpaUserCredentialStore implements UserCredentialStore { - - private final KeycloakSession session; - protected final EntityManager em; - - public JpaUserCredentialStore(KeycloakSession session, EntityManager em) { - this.session = session; - this.em = em; - } - - @Override - public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) { - CredentialEntity entity = em.find(CredentialEntity.class, cred.getId()); - if (entity == null) return; - entity.setAlgorithm(cred.getAlgorithm()); - entity.setCounter(cred.getCounter()); - entity.setCreatedDate(cred.getCreatedDate()); - entity.setDevice(cred.getDevice()); - entity.setDigits(cred.getDigits()); - entity.setHashIterations(cred.getHashIterations()); - entity.setPeriod(cred.getPeriod()); - entity.setSalt(cred.getSalt()); - entity.setType(cred.getType()); - entity.setValue(cred.getValue()); - if (entity.getCredentialAttributes().isEmpty() && (cred.getConfig() == null || cred.getConfig().isEmpty())) { - - } else { - MultivaluedHashMap attrs = cred.getConfig(); - MultivaluedHashMap config = cred.getConfig(); - if (config == null) config = new MultivaluedHashMap<>(); - - Iterator it = entity.getCredentialAttributes().iterator(); - while (it.hasNext()) { - CredentialAttributeEntity attr = it.next(); - List values = config.getList(attr.getName()); - if (values == null || !values.contains(attr.getValue())) { - em.remove(attr); - it.remove(); - } else { - attrs.add(attr.getName(), attr.getValue()); - } - - } - for (String key : config.keySet()) { - List values = config.getList(key); - List attrValues = attrs.getList(key); - for (String val : values) { - if (attrValues == null || !attrValues.contains(val)) { - CredentialAttributeEntity attr = new CredentialAttributeEntity(); - attr.setId(KeycloakModelUtils.generateId()); - attr.setValue(val); - attr.setName(key); - attr.setCredential(entity); - em.persist(attr); - entity.getCredentialAttributes().add(attr); - } - } - } - - } - - } - - @Override - public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) { - CredentialEntity entity = new CredentialEntity(); - String id = cred.getId() == null ? KeycloakModelUtils.generateId() : cred.getId(); - entity.setId(id); - entity.setAlgorithm(cred.getAlgorithm()); - entity.setCounter(cred.getCounter()); - entity.setCreatedDate(cred.getCreatedDate()); - entity.setDevice(cred.getDevice()); - entity.setDigits(cred.getDigits()); - entity.setHashIterations(cred.getHashIterations()); - entity.setPeriod(cred.getPeriod()); - entity.setSalt(cred.getSalt()); - entity.setType(cred.getType()); - entity.setValue(cred.getValue()); - UserEntity userRef = em.getReference(UserEntity.class, user.getId()); - entity.setUser(userRef); - em.persist(entity); - MultivaluedHashMap config = cred.getConfig(); - if (config != null || !config.isEmpty()) { - - for (String key : config.keySet()) { - List values = config.getList(key); - for (String val : values) { - CredentialAttributeEntity attr = new CredentialAttributeEntity(); - attr.setId(KeycloakModelUtils.generateId()); - attr.setValue(val); - attr.setName(key); - attr.setCredential(entity); - em.persist(attr); - entity.getCredentialAttributes().add(attr); - } - } - - } - return toModel(entity); - } - - @Override - public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) { - CredentialEntity entity = em.find(CredentialEntity.class, id); - if (entity == null) return false; - em.remove(entity); - return true; - } - - @Override - public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) { - CredentialEntity entity = em.find(CredentialEntity.class, id); - if (entity == null) return null; - CredentialModel model = toModel(entity); - return model; - } - - protected CredentialModel toModel(CredentialEntity entity) { - CredentialModel model = new CredentialModel(); - model.setId(entity.getId()); - model.setType(entity.getType()); - model.setValue(entity.getValue()); - model.setAlgorithm(entity.getAlgorithm()); - model.setSalt(entity.getSalt()); - model.setPeriod(entity.getPeriod()); - model.setCounter(entity.getCounter()); - model.setCreatedDate(entity.getCreatedDate()); - model.setDevice(entity.getDevice()); - model.setDigits(entity.getDigits()); - MultivaluedHashMap config = new MultivaluedHashMap<>(); - model.setConfig(config); - for (CredentialAttributeEntity attr : entity.getCredentialAttributes()) { - config.add(attr.getName(), attr.getValue()); - } - return model; - } - - @Override - public List getStoredCredentials(RealmModel realm, UserModel user) { - UserEntity userEntity = em.getReference(UserEntity.class, user.getId()); - TypedQuery query = em.createNamedQuery("credentialByUser", CredentialEntity.class) - .setParameter("user", userEntity); - List results = query.getResultList(); - List rtn = new LinkedList<>(); - for (CredentialEntity entity : results) { - rtn.add(toModel(entity)); - } - return rtn; - } - - @Override - public List getStoredCredentialsByType(RealmModel realm, UserModel user, String type) { - UserEntity userEntity = em.getReference(UserEntity.class, user.getId()); - TypedQuery query = em.createNamedQuery("credentialByUserAndType", CredentialEntity.class) - .setParameter("type", type) - .setParameter("user", userEntity); - List results = query.getResultList(); - List rtn = new LinkedList<>(); - for (CredentialEntity entity : results) { - rtn.add(toModel(entity)); - } - return rtn; - } - - @Override - public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) { - UserEntity userEntity = em.getReference(UserEntity.class, user.getId()); - TypedQuery query = em.createNamedQuery("credentialByNameAndType", CredentialEntity.class) - .setParameter("type", type) - .setParameter("device", name) - .setParameter("user", userEntity); - List results = query.getResultList(); - if (results.isEmpty()) return null; - return toModel(results.get(0)); - } - - @Override - public void close() { - - } -} diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserCredentialStoreFactory.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserCredentialStoreFactory.java deleted file mode 100755 index 550299ba8b..0000000000 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserCredentialStoreFactory.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.models.jpa; - -import org.keycloak.Config; -import org.keycloak.connections.jpa.JpaConnectionProvider; -import org.keycloak.credential.UserCredentialStore; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.provider.ProviderFactory; - -import javax.persistence.EntityManager; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class JpaUserCredentialStoreFactory implements ProviderFactory { - - @Override - public void init(Config.Scope config) { - } - - @Override - public void postInit(KeycloakSessionFactory factory) { - - } - - @Override - public String getId() { - return "jpa"; - } - - @Override - public UserCredentialStore create(KeycloakSession session) { - EntityManager em = session.getProvider(JpaConnectionProvider.class).getEntityManager(); - return new JpaUserCredentialStore(session, em); - } - - @Override - public void close() { - } - -} diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java index d44c6fe171..0d938d61bb 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java @@ -17,11 +17,7 @@ package org.keycloak.models.jpa; -import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.component.ComponentModel; -import org.keycloak.credential.CredentialInput; -import org.keycloak.credential.CredentialModel; -import org.keycloak.credential.UserCredentialStore; import org.keycloak.models.ClientModel; import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.FederatedIdentityModel; @@ -38,8 +34,6 @@ import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; -import org.keycloak.models.jpa.entities.CredentialAttributeEntity; -import org.keycloak.models.jpa.entities.CredentialEntity; import org.keycloak.models.jpa.entities.FederatedIdentityEntity; import org.keycloak.models.jpa.entities.UserAttributeEntity; import org.keycloak.models.jpa.entities.UserConsentEntity; @@ -54,9 +48,7 @@ import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -66,7 +58,7 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class JpaUserProvider implements UserProvider, UserCredentialStore { +public class JpaUserProvider implements UserProvider { private static final String EMAIL = "email"; private static final String USERNAME = "username"; @@ -375,8 +367,6 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore { .setParameter("realmId", realm.getId()).executeUpdate(); num = em.createNamedQuery("deleteFederatedIdentityByRealm") .setParameter("realmId", realm.getId()).executeUpdate(); - num = em.createNamedQuery("deleteCredentialAttributeByRealm") - .setParameter("realmId", realm.getId()).executeUpdate(); num = em.createNamedQuery("deleteCredentialsByRealm") .setParameter("realmId", realm.getId()).executeUpdate(); num = em.createNamedQuery("deleteUserAttributesByRealm") @@ -401,10 +391,6 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore { .setParameter("realmId", realm.getId()) .setParameter("link", link.getId()) .executeUpdate(); - num = em.createNamedQuery("deleteCredentialAttributeByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); num = em.createNamedQuery("deleteCredentialsByRealmAndLink") .setParameter("realmId", realm.getId()) .setParameter("link", link.getId()) @@ -730,174 +716,4 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore { public void preRemove(RealmModel realm, ComponentModel component) { } - - @Override - public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) { - CredentialEntity entity = em.find(CredentialEntity.class, cred.getId()); - if (entity == null) return; - entity.setAlgorithm(cred.getAlgorithm()); - entity.setCounter(cred.getCounter()); - entity.setCreatedDate(cred.getCreatedDate()); - entity.setDevice(cred.getDevice()); - entity.setDigits(cred.getDigits()); - entity.setHashIterations(cred.getHashIterations()); - entity.setPeriod(cred.getPeriod()); - entity.setSalt(cred.getSalt()); - entity.setType(cred.getType()); - entity.setValue(cred.getValue()); - if (entity.getCredentialAttributes().isEmpty() && (cred.getConfig() == null || cred.getConfig().isEmpty())) { - - } else { - MultivaluedHashMap attrs = cred.getConfig(); - MultivaluedHashMap config = cred.getConfig(); - if (config == null) config = new MultivaluedHashMap<>(); - - Iterator it = entity.getCredentialAttributes().iterator(); - while (it.hasNext()) { - CredentialAttributeEntity attr = it.next(); - List values = config.getList(attr.getName()); - if (values == null || !values.contains(attr.getValue())) { - em.remove(attr); - it.remove(); - } else { - attrs.add(attr.getName(), attr.getValue()); - } - - } - for (String key : config.keySet()) { - List values = config.getList(key); - List attrValues = attrs.getList(key); - for (String val : values) { - if (attrValues == null || !attrValues.contains(val)) { - CredentialAttributeEntity attr = new CredentialAttributeEntity(); - attr.setId(KeycloakModelUtils.generateId()); - attr.setValue(val); - attr.setName(key); - attr.setCredential(entity); - em.persist(attr); - entity.getCredentialAttributes().add(attr); - } - } - } - - } - - } - - @Override - public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) { - CredentialEntity entity = new CredentialEntity(); - String id = cred.getId() == null ? KeycloakModelUtils.generateId() : cred.getId(); - entity.setId(id); - entity.setAlgorithm(cred.getAlgorithm()); - entity.setCounter(cred.getCounter()); - entity.setCreatedDate(cred.getCreatedDate()); - entity.setDevice(cred.getDevice()); - entity.setDigits(cred.getDigits()); - entity.setHashIterations(cred.getHashIterations()); - entity.setPeriod(cred.getPeriod()); - entity.setSalt(cred.getSalt()); - entity.setType(cred.getType()); - entity.setValue(cred.getValue()); - UserEntity userRef = em.getReference(UserEntity.class, user.getId()); - entity.setUser(userRef); - em.persist(entity); - MultivaluedHashMap config = cred.getConfig(); - if (config != null || !config.isEmpty()) { - - for (String key : config.keySet()) { - List values = config.getList(key); - for (String val : values) { - CredentialAttributeEntity attr = new CredentialAttributeEntity(); - attr.setId(KeycloakModelUtils.generateId()); - attr.setValue(val); - attr.setName(key); - attr.setCredential(entity); - em.persist(attr); - entity.getCredentialAttributes().add(attr); - } - } - - } - return toModel(entity); - } - - @Override - public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) { - CredentialEntity entity = em.find(CredentialEntity.class, id); - if (entity == null) return false; - em.remove(entity); - return true; - } - - @Override - public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) { - CredentialEntity entity = em.find(CredentialEntity.class, id); - if (entity == null) return null; - CredentialModel model = toModel(entity); - return model; - } - - protected CredentialModel toModel(CredentialEntity entity) { - CredentialModel model = new CredentialModel(); - model.setId(entity.getId()); - model.setType(entity.getType()); - model.setValue(entity.getValue()); - model.setAlgorithm(entity.getAlgorithm()); - model.setSalt(entity.getSalt()); - model.setPeriod(entity.getPeriod()); - model.setCounter(entity.getCounter()); - model.setCreatedDate(entity.getCreatedDate()); - model.setDevice(entity.getDevice()); - model.setDigits(entity.getDigits()); - MultivaluedHashMap config = new MultivaluedHashMap<>(); - model.setConfig(config); - for (CredentialAttributeEntity attr : entity.getCredentialAttributes()) { - config.add(attr.getName(), attr.getValue()); - } - return model; - } - - @Override - public List getStoredCredentials(RealmModel realm, UserModel user) { - UserEntity userEntity = em.getReference(UserEntity.class, user.getId()); - TypedQuery query = em.createNamedQuery("credentialByUser", CredentialEntity.class) - .setParameter("user", userEntity); - List results = query.getResultList(); - List rtn = new LinkedList<>(); - for (CredentialEntity entity : results) { - rtn.add(toModel(entity)); - } - return rtn; - } - - @Override - public List getStoredCredentialsByType(RealmModel realm, UserModel user, String type) { - UserEntity userEntity = em.getReference(UserEntity.class, user.getId()); - TypedQuery query = em.createNamedQuery("credentialByUserAndType", CredentialEntity.class) - .setParameter("type", type) - .setParameter("user", userEntity); - List results = query.getResultList(); - List rtn = new LinkedList<>(); - for (CredentialEntity entity : results) { - rtn.add(toModel(entity)); - } - return rtn; - } - - @Override - public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) { - UserEntity userEntity = em.getReference(UserEntity.class, user.getId()); - TypedQuery query = em.createNamedQuery("credentialByNameAndType", CredentialEntity.class) - .setParameter("type", type) - .setParameter("device", name) - .setParameter("user", userEntity); - List results = query.getResultList(); - if (results.isEmpty()) return null; - return toModel(results.get(0)); - } - - - - } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialAttributeEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialAttributeEntity.java deleted file mode 100755 index f4ceb947ee..0000000000 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialAttributeEntity.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.models.jpa.entities; - -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -@NamedQueries({ - @NamedQuery(name="getCredentialAttribute", query="select attr from CredentialAttributeEntity attr where attr.credential = :credential"), - @NamedQuery(name="deleteCredentialAttributeByCredential", query="delete from CredentialAttributeEntity attr where attr.credential = :credential"), - @NamedQuery(name="deleteCredentialAttributeByRealm", query="delete from CredentialAttributeEntity attr where attr.credential IN (select cred from CredentialEntity cred where cred.user IN (select u from UserEntity u where u.realmId=:realmId))"), - @NamedQuery(name="deleteCredentialAttributeByRealmAndLink", query="delete from CredentialAttributeEntity attr where attr.credential IN (select cred from CredentialEntity cred where cred.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link))"), - @NamedQuery(name="deleteCredentialAttributeByUser", query="delete from CredentialAttributeEntity attr where attr.credential IN (select cred from CredentialEntity cred where cred.user = :user)"), -}) -@Table(name="CREDENTIAL_ATTRIBUTE") -@Entity -public class CredentialAttributeEntity { - - @Id - @Column(name="ID", length = 36) - @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL - protected String id; - - @ManyToOne(fetch= FetchType.LAZY) - @JoinColumn(name = "CREDENTIAL_ID") - protected CredentialEntity credential; - - @Column(name = "NAME") - protected String name; - @Column(name = "VALUE") - protected String value; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public CredentialEntity getCredential() { - return credential; - } - - public void setCredential(CredentialEntity credential) { - this.credential = credential; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null) return false; - if (!(o instanceof CredentialAttributeEntity)) return false; - - CredentialAttributeEntity that = (CredentialAttributeEntity) o; - - if (!id.equals(that.getId())) return false; - - return true; - } - - @Override - public int hashCode() { - return id.hashCode(); - } - -} diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java index 4c8f0b3e83..ceb284cb06 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java @@ -19,7 +19,6 @@ package org.keycloak.models.jpa.entities; import javax.persistence.Access; import javax.persistence.AccessType; -import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -28,19 +27,14 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; import javax.persistence.Table; -import java.util.ArrayList; -import java.util.Collection; /** * @author Bill Burke * @version $Revision: 1 $ */ @NamedQueries({ - @NamedQuery(name="credentialByUser", query="select cred from CredentialEntity cred where cred.user = :user"), @NamedQuery(name="credentialByUserAndType", query="select cred from CredentialEntity cred where cred.user = :user and cred.type = :type"), - @NamedQuery(name="credentialByNameAndType", query="select cred from CredentialEntity cred where cred.user = :user and cred.type = :type and cred.device = :device"), @NamedQuery(name="deleteCredentialsByRealm", query="delete from CredentialEntity cred where cred.user IN (select u from UserEntity u where u.realmId=:realmId)"), @NamedQuery(name="deleteCredentialsByRealmAndLink", query="delete from CredentialEntity cred where cred.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link)") @@ -80,8 +74,6 @@ public class CredentialEntity { @Column(name="PERIOD") protected int period; - @OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, orphanRemoval = true, mappedBy="credential") - protected Collection credentialAttributes = new ArrayList<>(); public String getId() { return id; @@ -179,14 +171,6 @@ public class CredentialEntity { this.period = period; } - public Collection getCredentialAttributes() { - return credentialAttributes; - } - - public void setCredentialAttributes(Collection credentialAttributes) { - this.credentialAttributes = credentialAttributes; - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaFederatedUserCredentialStore.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaFederatedUserCredentialStore.java deleted file mode 100644 index 13fa03218f..0000000000 --- a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaFederatedUserCredentialStore.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.storage.jpa; - -import org.keycloak.common.util.MultivaluedHashMap; -import org.keycloak.credential.CredentialModel; -import org.keycloak.credential.UserCredentialStore; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.storage.StorageId; -import org.keycloak.storage.jpa.entity.FederatedUserCredentialAttributeEntity; -import org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity; - -import javax.persistence.EntityManager; -import javax.persistence.TypedQuery; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class JpaFederatedUserCredentialStore implements UserCredentialStore { - - private final KeycloakSession session; - protected final EntityManager em; - - public JpaFederatedUserCredentialStore(KeycloakSession session, EntityManager em) { - this.session = session; - this.em = em; - } - - @Override - public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) { - FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, cred.getId()); - if (entity == null) return; - entity.setAlgorithm(cred.getAlgorithm()); - entity.setCounter(cred.getCounter()); - entity.setCreatedDate(cred.getCreatedDate()); - entity.setDevice(cred.getDevice()); - entity.setDigits(cred.getDigits()); - entity.setHashIterations(cred.getHashIterations()); - entity.setPeriod(cred.getPeriod()); - entity.setSalt(cred.getSalt()); - entity.setType(cred.getType()); - entity.setValue(cred.getValue()); - if (entity.getCredentialAttributes().isEmpty() && (cred.getConfig() == null || cred.getConfig().isEmpty())) { - - } else { - MultivaluedHashMap attrs = cred.getConfig(); - MultivaluedHashMap config = cred.getConfig(); - if (config == null) config = new MultivaluedHashMap<>(); - - Iterator it = entity.getCredentialAttributes().iterator(); - while (it.hasNext()) { - FederatedUserCredentialAttributeEntity attr = it.next(); - List values = config.getList(attr.getName()); - if (values == null || !values.contains(attr.getValue())) { - em.remove(attr); - it.remove(); - } else { - attrs.add(attr.getName(), attr.getValue()); - } - - } - for (String key : config.keySet()) { - List values = config.getList(key); - List attrValues = attrs.getList(key); - for (String val : values) { - if (attrValues == null || !attrValues.contains(val)) { - FederatedUserCredentialAttributeEntity attr = new FederatedUserCredentialAttributeEntity(); - attr.setId(KeycloakModelUtils.generateId()); - attr.setValue(val); - attr.setName(key); - attr.setCredential(entity); - em.persist(attr); - entity.getCredentialAttributes().add(attr); - } - } - } - - } - - } - - @Override - public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) { - FederatedUserCredentialEntity entity = new FederatedUserCredentialEntity(); - String id = cred.getId() == null ? KeycloakModelUtils.generateId() : cred.getId(); - entity.setId(id); - entity.setAlgorithm(cred.getAlgorithm()); - entity.setCounter(cred.getCounter()); - entity.setCreatedDate(cred.getCreatedDate()); - entity.setDevice(cred.getDevice()); - entity.setDigits(cred.getDigits()); - entity.setHashIterations(cred.getHashIterations()); - entity.setPeriod(cred.getPeriod()); - entity.setSalt(cred.getSalt()); - entity.setType(cred.getType()); - entity.setValue(cred.getValue()); - entity.setUserId(user.getId()); - entity.setRealmId(realm.getId()); - entity.setStorageProviderId(StorageId.resolveProviderId(user)); - em.persist(entity); - MultivaluedHashMap config = cred.getConfig(); - if (config != null || !config.isEmpty()) { - - for (String key : config.keySet()) { - List values = config.getList(key); - for (String val : values) { - FederatedUserCredentialAttributeEntity attr = new FederatedUserCredentialAttributeEntity(); - attr.setId(KeycloakModelUtils.generateId()); - attr.setValue(val); - attr.setName(key); - attr.setCredential(entity); - em.persist(attr); - entity.getCredentialAttributes().add(attr); - } - } - - } - return toModel(entity); - } - - @Override - public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) { - FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, id); - if (entity == null) return false; - em.remove(entity); - return true; - } - - @Override - public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) { - FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, id); - if (entity == null) return null; - CredentialModel model = toModel(entity); - return model; - } - - protected CredentialModel toModel(FederatedUserCredentialEntity entity) { - CredentialModel model = new CredentialModel(); - model.setId(entity.getId()); - model.setType(entity.getType()); - model.setValue(entity.getValue()); - model.setAlgorithm(entity.getAlgorithm()); - model.setSalt(entity.getSalt()); - model.setPeriod(entity.getPeriod()); - model.setCounter(entity.getCounter()); - model.setCreatedDate(entity.getCreatedDate()); - model.setDevice(entity.getDevice()); - model.setDigits(entity.getDigits()); - MultivaluedHashMap config = new MultivaluedHashMap<>(); - model.setConfig(config); - for (FederatedUserCredentialAttributeEntity attr : entity.getCredentialAttributes()) { - config.add(attr.getName(), attr.getValue()); - } - return model; - } - - @Override - public List getStoredCredentials(RealmModel realm, UserModel user) { - TypedQuery query = em.createNamedQuery("federatedUserCredentialByUser", FederatedUserCredentialEntity.class) - .setParameter("userId", user.getId()); - List results = query.getResultList(); - List rtn = new LinkedList<>(); - for (FederatedUserCredentialEntity entity : results) { - rtn.add(toModel(entity)); - } - return rtn; - } - - @Override - public List getStoredCredentialsByType(RealmModel realm, UserModel user, String type) { - TypedQuery query = em.createNamedQuery("federatedUserCredentialByUserAndType", FederatedUserCredentialEntity.class) - .setParameter("type", type) - .setParameter("userId", user.getId()); - List results = query.getResultList(); - List rtn = new LinkedList<>(); - for (FederatedUserCredentialEntity entity : results) { - rtn.add(toModel(entity)); - } - return rtn; - } - - @Override - public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) { - TypedQuery query = em.createNamedQuery("federatedUserCredentialByNameAndType", FederatedUserCredentialEntity.class) - .setParameter("type", type) - .setParameter("device", name) - .setParameter("userId", user.getId()); - List results = query.getResultList(); - if (results.isEmpty()) return null; - return toModel(results.get(0)); - } - - @Override - public void close() { - - } -} diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java index 1c72da0744..f6710dd3d5 100644 --- a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java +++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java @@ -18,8 +18,6 @@ package org.keycloak.storage.jpa; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.component.ComponentModel; -import org.keycloak.credential.CredentialModel; -import org.keycloak.credential.UserCredentialStore; import org.keycloak.models.ClientModel; import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.GroupModel; @@ -51,7 +49,6 @@ import org.keycloak.storage.jpa.entity.FederatedUserAttributeEntity; import org.keycloak.storage.jpa.entity.FederatedUserConsentEntity; import org.keycloak.storage.jpa.entity.FederatedUserConsentProtocolMapperEntity; import org.keycloak.storage.jpa.entity.FederatedUserConsentRoleEntity; -import org.keycloak.storage.jpa.entity.FederatedUserCredentialAttributeEntity; import org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity; import org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity; import org.keycloak.storage.jpa.entity.FederatedUserRequiredActionEntity; @@ -62,7 +59,6 @@ import javax.persistence.TypedQuery; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -79,8 +75,7 @@ public class JpaUserFederatedStorageProvider implements UserCredentialsFederatedStorage, UserGroupMembershipFederatedStorage, UserRequiredActionsFederatedStorage, - UserRoleMappingsFederatedStorage, - UserCredentialStore { + UserRoleMappingsFederatedStorage { private final KeycloakSession session; protected EntityManager em; @@ -611,200 +606,6 @@ public class JpaUserFederatedStorageProvider implements em.flush(); } - @Override - public boolean removeCredential(RealmModel realm, String id) { - return false; - } - - @Override - public CredentialModel getCredentialById(String id) { - return null; - } - - @Override - public List getCredentials(RealmModel realm) { - return null; - } - - @Override - public List getUserCredentials(RealmModel realm, UserModel user) { - return null; - } - - @Override - public List getCredentialsByType(RealmModel realm, UserModel user, String type) { - return null; - } - - @Override - public CredentialModel getCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) { - return null; - } - - @Override - public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) { - FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, cred.getId()); - if (entity == null) return; - entity.setAlgorithm(cred.getAlgorithm()); - entity.setCounter(cred.getCounter()); - entity.setCreatedDate(cred.getCreatedDate()); - entity.setDevice(cred.getDevice()); - entity.setDigits(cred.getDigits()); - entity.setHashIterations(cred.getHashIterations()); - entity.setPeriod(cred.getPeriod()); - entity.setSalt(cred.getSalt()); - entity.setType(cred.getType()); - entity.setValue(cred.getValue()); - if (entity.getCredentialAttributes().isEmpty() && (cred.getConfig() == null || cred.getConfig().isEmpty())) { - - } else { - MultivaluedHashMap attrs = cred.getConfig(); - MultivaluedHashMap config = cred.getConfig(); - if (config == null) config = new MultivaluedHashMap<>(); - - Iterator it = entity.getCredentialAttributes().iterator(); - while (it.hasNext()) { - FederatedUserCredentialAttributeEntity attr = it.next(); - List values = config.getList(attr.getName()); - if (values == null || !values.contains(attr.getValue())) { - em.remove(attr); - it.remove(); - } else { - attrs.add(attr.getName(), attr.getValue()); - } - - } - for (String key : config.keySet()) { - List values = config.getList(key); - List attrValues = attrs.getList(key); - for (String val : values) { - if (attrValues == null || !attrValues.contains(val)) { - FederatedUserCredentialAttributeEntity attr = new FederatedUserCredentialAttributeEntity(); - attr.setId(KeycloakModelUtils.generateId()); - attr.setValue(val); - attr.setName(key); - attr.setCredential(entity); - em.persist(attr); - entity.getCredentialAttributes().add(attr); - } - } - } - - } - - } - - @Override - public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) { - FederatedUserCredentialEntity entity = new FederatedUserCredentialEntity(); - String id = cred.getId() == null ? KeycloakModelUtils.generateId() : cred.getId(); - entity.setId(id); - entity.setAlgorithm(cred.getAlgorithm()); - entity.setCounter(cred.getCounter()); - entity.setCreatedDate(cred.getCreatedDate()); - entity.setDevice(cred.getDevice()); - entity.setDigits(cred.getDigits()); - entity.setHashIterations(cred.getHashIterations()); - entity.setPeriod(cred.getPeriod()); - entity.setSalt(cred.getSalt()); - entity.setType(cred.getType()); - entity.setValue(cred.getValue()); - entity.setUserId(user.getId()); - entity.setRealmId(realm.getId()); - entity.setStorageProviderId(StorageId.resolveProviderId(user)); - em.persist(entity); - MultivaluedHashMap config = cred.getConfig(); - if (config != null || !config.isEmpty()) { - - for (String key : config.keySet()) { - List values = config.getList(key); - for (String val : values) { - FederatedUserCredentialAttributeEntity attr = new FederatedUserCredentialAttributeEntity(); - attr.setId(KeycloakModelUtils.generateId()); - attr.setValue(val); - attr.setName(key); - attr.setCredential(entity); - em.persist(attr); - entity.getCredentialAttributes().add(attr); - } - } - - } - return toModel(entity); - } - - @Override - public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) { - FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, id); - if (entity == null) return false; - em.remove(entity); - return true; - } - - @Override - public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) { - FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, id); - if (entity == null) return null; - CredentialModel model = toModel(entity); - return model; - } - - protected CredentialModel toModel(FederatedUserCredentialEntity entity) { - CredentialModel model = new CredentialModel(); - model.setId(entity.getId()); - model.setType(entity.getType()); - model.setValue(entity.getValue()); - model.setAlgorithm(entity.getAlgorithm()); - model.setSalt(entity.getSalt()); - model.setPeriod(entity.getPeriod()); - model.setCounter(entity.getCounter()); - model.setCreatedDate(entity.getCreatedDate()); - model.setDevice(entity.getDevice()); - model.setDigits(entity.getDigits()); - MultivaluedHashMap config = new MultivaluedHashMap<>(); - model.setConfig(config); - for (FederatedUserCredentialAttributeEntity attr : entity.getCredentialAttributes()) { - config.add(attr.getName(), attr.getValue()); - } - return model; - } - - @Override - public List getStoredCredentials(RealmModel realm, UserModel user) { - TypedQuery query = em.createNamedQuery("federatedUserCredentialByUser", FederatedUserCredentialEntity.class) - .setParameter("userId", user.getId()); - List results = query.getResultList(); - List rtn = new LinkedList<>(); - for (FederatedUserCredentialEntity entity : results) { - rtn.add(toModel(entity)); - } - return rtn; - } - - @Override - public List getStoredCredentialsByType(RealmModel realm, UserModel user, String type) { - TypedQuery query = em.createNamedQuery("federatedUserCredentialByUserAndType", FederatedUserCredentialEntity.class) - .setParameter("type", type) - .setParameter("userId", user.getId()); - List results = query.getResultList(); - List rtn = new LinkedList<>(); - for (FederatedUserCredentialEntity entity : results) { - rtn.add(toModel(entity)); - } - return rtn; - } - - @Override - public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) { - TypedQuery query = em.createNamedQuery("federatedUserCredentialByNameAndType", FederatedUserCredentialEntity.class) - .setParameter("type", type) - .setParameter("device", name) - .setParameter("userId", user.getId()); - List results = query.getResultList(); - if (results.isEmpty()) return null; - return toModel(results.get(0)); - } - @Override public void preRemove(RealmModel realm) { int num = em.createNamedQuery("deleteFederatedUserConsentRolesByRealm") @@ -819,8 +620,6 @@ public class JpaUserFederatedStorageProvider implements .setParameter("realmId", realm.getId()).executeUpdate(); num = em.createNamedQuery("deleteBrokerLinkByRealm") .setParameter("realmId", realm.getId()).executeUpdate(); - num = em.createNamedQuery("deleteFederatedCredentialAttributeByRealm") - .setParameter("realmId", realm.getId()).executeUpdate(); num = em.createNamedQuery("deleteFederatedUserCredentialsByRealm") .setParameter("realmId", realm.getId()).executeUpdate(); num = em.createNamedQuery("deleteUserFederatedAttributesByRealm") @@ -843,10 +642,6 @@ public class JpaUserFederatedStorageProvider implements .setParameter("realmId", realm.getId()) .setParameter("link", link.getId()) .executeUpdate(); - num = em.createNamedQuery("deleteFederatedCredentialAttributeByRealmAndLink") - .setParameter("realmId", realm.getId()) - .setParameter("link", link.getId()) - .executeUpdate(); num = em.createNamedQuery("deleteFederatedUserCredentialsByRealmAndLink") .setParameter("realmId", realm.getId()) .setParameter("link", link.getId()) @@ -904,10 +699,6 @@ public class JpaUserFederatedStorageProvider implements .setParameter("userId", user.getId()) .setParameter("realmId", realm.getId()) .executeUpdate(); - em.createNamedQuery("deleteFederatedCredentialAttributeByUser") - .setParameter("userId", user.getId()) - .setParameter("realmId", realm.getId()) - .executeUpdate(); em.createNamedQuery("deleteFederatedUserCredentialByUser") .setParameter("userId", user.getId()) .setParameter("realmId", realm.getId()) @@ -946,9 +737,6 @@ public class JpaUserFederatedStorageProvider implements em.createNamedQuery("deleteFederatedUserConsentsByStorageProvider") .setParameter("storageProviderId", model.getId()) .executeUpdate(); - em.createNamedQuery("deleteFederatedCredentialAttributeByStorageProvider") - .setParameter("storageProviderId", model.getId()) - .executeUpdate(); em.createNamedQuery("deleteFederatedUserCredentialsByStorageProvider") .setParameter("storageProviderId", model.getId()) .executeUpdate(); diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserCredentialAttributeEntity.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserCredentialAttributeEntity.java deleted file mode 100755 index c6a15b38ab..0000000000 --- a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserCredentialAttributeEntity.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.storage.jpa.entity; - -import org.keycloak.models.jpa.entities.CredentialEntity; - -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -@NamedQueries({ - @NamedQuery(name="deleteFederatedCredentialAttributeByCredential", query="delete from FederatedUserCredentialAttributeEntity attr where attr.credential = :credential"), - @NamedQuery(name="deleteFederatedCredentialAttributeByStorageProvider", query="delete from FederatedUserCredentialAttributeEntity attr where attr.credential IN (select cred from FederatedUserCredentialEntity cred where cred.storageProviderId=:storageProviderId)"), - @NamedQuery(name="deleteFederatedCredentialAttributeByRealm", query="delete from FederatedUserCredentialAttributeEntity attr where attr.credential IN (select cred from FederatedUserCredentialEntity cred where cred.realmId=:realmId)"), - @NamedQuery(name="deleteFederatedCredentialAttributeByRealmAndLink", query="delete from FederatedUserCredentialAttributeEntity attr where attr.credential IN (select cred from FederatedUserCredentialEntity cred where cred.userId IN (select u.id from UserEntity u where u.realmId=:realmId and u.federationLink=:link))"), - @NamedQuery(name="deleteFederatedCredentialAttributeByUser", query="delete from FederatedUserCredentialAttributeEntity attr where attr.credential IN (select cred from FederatedUserCredentialEntity cred where cred.userId = :userId and cred.realmId = :realmId)"), -}) -@Table(name="FED_CREDENTIAL_ATTRIBUTE") -@Entity -public class FederatedUserCredentialAttributeEntity { - - @Id - @Column(name="ID", length = 36) - @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL - protected String id; - - @ManyToOne(fetch= FetchType.LAZY) - @JoinColumn(name = "CREDENTIAL_ID") - protected FederatedUserCredentialEntity credential; - - @Column(name = "NAME") - protected String name; - @Column(name = "VALUE") - protected String value; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public FederatedUserCredentialEntity getCredential() { - return credential; - } - - public void setCredential(FederatedUserCredentialEntity credential) { - this.credential = credential; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null) return false; - if (!(o instanceof FederatedUserCredentialAttributeEntity)) return false; - - FederatedUserCredentialAttributeEntity that = (FederatedUserCredentialAttributeEntity) o; - - if (!id.equals(that.getId())) return false; - - return true; - } - - @Override - public int hashCode() { - return id.hashCode(); - } - -} diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserCredentialEntity.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserCredentialEntity.java index 52a757cd8f..996608b0b3 100755 --- a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserCredentialEntity.java +++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserCredentialEntity.java @@ -17,12 +17,10 @@ package org.keycloak.storage.jpa.entity; -import org.keycloak.models.jpa.entities.CredentialEntity; import org.keycloak.models.jpa.entities.UserEntity; import javax.persistence.Access; import javax.persistence.AccessType; -import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -31,10 +29,7 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; import javax.persistence.Table; -import java.util.ArrayList; -import java.util.Collection; /** * @author Bill Burke @@ -43,7 +38,6 @@ import java.util.Collection; @NamedQueries({ @NamedQuery(name="federatedUserCredentialByUser", query="select cred from FederatedUserCredentialEntity cred where cred.userId = :userId"), @NamedQuery(name="federatedUserCredentialByUserAndType", query="select cred from FederatedUserCredentialEntity cred where cred.userId = :userId and cred.type = :type"), - @NamedQuery(name="federatedUserCredentialByNameAndType", query="select cred from FederatedUserCredentialEntity cred where cred.userId = :userId and cred.type = :type and cred.device = :device"), @NamedQuery(name="deleteFederatedUserCredentialByUser", query="delete from FederatedUserCredentialEntity cred where cred.userId = :userId and cred.realmId = :realmId"), @NamedQuery(name="deleteFederatedUserCredentialByUserAndType", query="delete from FederatedUserCredentialEntity cred where cred.userId = :userId and cred.type = :type"), @NamedQuery(name="deleteFederatedUserCredentialByUserAndTypeAndDevice", query="delete from FederatedUserCredentialEntity cred where cred.userId = :userId and cred.type = :type and cred.device = :device"), @@ -93,8 +87,6 @@ public class FederatedUserCredentialEntity { protected int digits; @Column(name="PERIOD") protected int period; - @OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, orphanRemoval = true, mappedBy="credential") - protected Collection credentialAttributes = new ArrayList<>(); public String getId() { @@ -209,14 +201,6 @@ public class FederatedUserCredentialEntity { this.period = period; } - public Collection getCredentialAttributes() { - return credentialAttributes; - } - - public void setCredentialAttributes(Collection credentialAttributes) { - this.credentialAttributes = credentialAttributes; - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml index a9b60787ca..63afbb2dcf 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml @@ -24,39 +24,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/persistence.xml b/model/jpa/src/main/resources/META-INF/persistence.xml index 6288fe5e2a..0b2ff231ed 100755 --- a/model/jpa/src/main/resources/META-INF/persistence.xml +++ b/model/jpa/src/main/resources/META-INF/persistence.xml @@ -22,7 +22,6 @@ org.keycloak.models.jpa.entities.ClientEntity org.keycloak.models.jpa.entities.CredentialEntity - org.keycloak.models.jpa.entities.CredentialAttributeEntity org.keycloak.models.jpa.entities.RealmEntity org.keycloak.models.jpa.entities.RealmAttributeEntity org.keycloak.models.jpa.entities.RequiredCredentialEntity @@ -75,7 +74,6 @@ org.keycloak.storage.jpa.entity.FederatedUserConsentRoleEntity org.keycloak.storage.jpa.entity.FederatedUserConsentProtocolMapperEntity org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity - org.keycloak.storage.jpa.entity.FederatedUserCredentialAttributeEntity org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity org.keycloak.storage.jpa.entity.FederatedUserRequiredActionEntity org.keycloak.storage.jpa.entity.FederatedUserRoleMappingEntity diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java index 9ad2c1ea36..c0537ba082 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java @@ -24,7 +24,6 @@ import com.mongodb.QueryBuilder; import org.keycloak.component.ComponentModel; import org.keycloak.connections.mongo.api.MongoStore; import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.credential.CredentialInput; import org.keycloak.models.ClientModel; import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.FederatedIdentityModel; @@ -636,5 +635,4 @@ public class MongoUserProvider implements UserProvider { public void preRemove(RealmModel realm, ComponentModel component) { } - } diff --git a/server-spi/src/main/java/org/keycloak/component/PrioritizedComponentModel.java b/server-spi/src/main/java/org/keycloak/component/PrioritizedComponentModel.java deleted file mode 100644 index 7a0393a4bc..0000000000 --- a/server-spi/src/main/java/org/keycloak/component/PrioritizedComponentModel.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.component; - -import org.keycloak.component.ComponentModel; -import org.keycloak.storage.UserStorageProviderModel; - -import java.util.Comparator; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class PrioritizedComponentModel extends ComponentModel { - public static Comparator comparator = new Comparator() { - @Override - public int compare(ComponentModel o1, ComponentModel o2) { - return parsePriority(o1) - parsePriority(o2); - } - }; - - public PrioritizedComponentModel(ComponentModel copy) { - super(copy); - } - - public PrioritizedComponentModel() { - } - - public static int parsePriority(ComponentModel component) { - String priority = component.getConfig().getFirst("priority"); - if (priority == null) return 0; - return Integer.valueOf(priority); - - } - - public int getPriority() { - return parsePriority(this); - - } - - public void setPriority(int priority) { - getConfig().putSingle("priority", Integer.toString(priority)); - } -} diff --git a/server-spi/src/main/java/org/keycloak/credential/CredentialInput.java b/server-spi/src/main/java/org/keycloak/credential/CredentialInput.java deleted file mode 100644 index 805fb25d68..0000000000 --- a/server-spi/src/main/java/org/keycloak/credential/CredentialInput.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.credential; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface CredentialInput { - String getType(); -} diff --git a/server-spi/src/main/java/org/keycloak/credential/CredentialInputUpdater.java b/server-spi/src/main/java/org/keycloak/credential/CredentialInputUpdater.java deleted file mode 100644 index 3456f8f5e1..0000000000 --- a/server-spi/src/main/java/org/keycloak/credential/CredentialInputUpdater.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.credential; - -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; - -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface CredentialInputUpdater { - boolean supportsCredentialType(String credentialType); - boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input); - void disableCredentialType(RealmModel realm, UserModel user, String credentialType); -} diff --git a/server-spi/src/main/java/org/keycloak/credential/CredentialInputValidator.java b/server-spi/src/main/java/org/keycloak/credential/CredentialInputValidator.java deleted file mode 100644 index a7a4c6d58a..0000000000 --- a/server-spi/src/main/java/org/keycloak/credential/CredentialInputValidator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.credential; - -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.provider.Provider; - -import java.util.List; -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface CredentialInputValidator { - boolean supportsCredentialType(String credentialType); - boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType); - boolean isValid(RealmModel realm, UserModel user, CredentialInput input); - -} diff --git a/server-spi/src/main/java/org/keycloak/credential/CredentialModel.java b/server-spi/src/main/java/org/keycloak/credential/CredentialModel.java deleted file mode 100755 index 24b7772398..0000000000 --- a/server-spi/src/main/java/org/keycloak/credential/CredentialModel.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.credential; - -import org.keycloak.common.util.MultivaluedHashMap; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; - -/** - * Used just in cases when we want to "directly" update or retrieve the hash or salt of user credential (For example during export/import) - * - * @author Marek Posolda - */ -public class CredentialModel implements Serializable { - public static final String PASSWORD = "password"; - public static final String PASSWORD_HISTORY = "password-history"; - public static final String PASSWORD_TOKEN = "password-token"; - - // Secret is same as password but it is not hashed - public static final String SECRET = "secret"; - public static final String TOTP = "totp"; - public static final String HOTP = "hotp"; - public static final String CLIENT_CERT = "cert"; - public static final String KERBEROS = "kerberos"; - public static final String OTP = "otp"; - - - - private String id; - private String type; - private String value; - private String device; - private byte[] salt; - private int hashIterations; - private Long createdDate; - - // otp stuff - private int counter; - private String algorithm; - private int digits; - private int period; - private MultivaluedHashMap config; - - - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getDevice() { - return device; - } - - public void setDevice(String device) { - this.device = device; - } - - public byte[] getSalt() { - return salt; - } - - public void setSalt(byte[] salt) { - this.salt = salt; - } - - public int getHashIterations() { - return hashIterations; - } - - public void setHashIterations(int iterations) { - this.hashIterations = iterations; - } - - public Long getCreatedDate() { - return createdDate; - } - - public void setCreatedDate(Long createdDate) { - this.createdDate = createdDate; - } - - public int getCounter() { - return counter; - } - - public void setCounter(int counter) { - this.counter = counter; - } - - public String getAlgorithm() { - return algorithm; - } - - public void setAlgorithm(String algorithm) { - this.algorithm = algorithm; - } - - public int getDigits() { - return digits; - } - - public void setDigits(int digits) { - this.digits = digits; - } - - public int getPeriod() { - return period; - } - - public void setPeriod(int period) { - this.period = period; - } - - public MultivaluedHashMap getConfig() { - return config; - } - - public void setConfig(MultivaluedHashMap config) { - this.config = config; - } -} diff --git a/server-spi/src/main/java/org/keycloak/credential/CredentialProvider.java b/server-spi/src/main/java/org/keycloak/credential/CredentialProvider.java deleted file mode 100644 index a8304339c5..0000000000 --- a/server-spi/src/main/java/org/keycloak/credential/CredentialProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.credential; - -import org.keycloak.provider.Provider; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface CredentialProvider extends Provider { - @Override - default - void close() { - - } -} diff --git a/server-spi/src/main/java/org/keycloak/credential/CredentialProviderFactory.java b/server-spi/src/main/java/org/keycloak/credential/CredentialProviderFactory.java deleted file mode 100755 index 480dd1c5c2..0000000000 --- a/server-spi/src/main/java/org/keycloak/credential/CredentialProviderFactory.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.credential; - -import org.keycloak.Config; -import org.keycloak.component.ComponentFactory; -import org.keycloak.component.ComponentModel; -import org.keycloak.component.ComponentValidationException; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.provider.ProviderConfigProperty; -import org.keycloak.storage.UserStorageProvider; - -import java.util.Collections; -import java.util.List; -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface CredentialProviderFactory extends ComponentFactory { - /** - * called per Keycloak transaction. - * - * @param session - * @param model - * @return - */ - T create(KeycloakSession session, ComponentModel model); - - /** - * This is the name of the provider and will be showed in the admin console as an option. - * - * @return - */ - @Override - String getId(); - - @Override - default void init(Config.Scope config) { - - } - - @Override - default void postInit(KeycloakSessionFactory factory) { - - } - - @Override - default void close() { - - } - - @Override - default String getHelpText() { - return ""; - } - - @Override - default List getConfigProperties() { - return Collections.EMPTY_LIST; - } - - @Override - default void validateConfiguration(KeycloakSession session, ComponentModel config) throws ComponentValidationException { - - } - -} diff --git a/server-spi/src/main/java/org/keycloak/credential/UserCredentialStore.java b/server-spi/src/main/java/org/keycloak/credential/UserCredentialStore.java deleted file mode 100644 index c99873911c..0000000000 --- a/server-spi/src/main/java/org/keycloak/credential/UserCredentialStore.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.credential; - -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.provider.Provider; - -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface UserCredentialStore extends Provider { - void updateCredential(RealmModel realm, UserModel user, CredentialModel cred); - CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred); - boolean removeStoredCredential(RealmModel realm, UserModel user, String id); - CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id); - List getStoredCredentials(RealmModel realm, UserModel user); - List getStoredCredentialsByType(RealmModel realm, UserModel user, String type); - CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type); -} diff --git a/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java b/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java index 2a1ad0ff4c..8b6dcd31d0 100755 --- a/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java +++ b/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java @@ -17,7 +17,6 @@ package org.keycloak.models; -import org.keycloak.models.cache.UserCache; import org.keycloak.provider.Provider; import org.keycloak.scripting.ScriptingProvider; import org.keycloak.storage.federated.UserFederatedStorageProvider; @@ -75,7 +74,6 @@ public interface KeycloakSession { Object removeAttribute(String attribute); void setAttribute(String name, Object value); - void enlistForClose(Provider provider); KeycloakSessionFactory getKeycloakSessionFactory(); @@ -103,14 +101,7 @@ public interface KeycloakSession { void close(); /** - * The user cache - * - * @return may be null if cache is disabled - */ - UserCache getUserCache(); - - /** - * A possibly cached view of all users in system. + * A cached view of all users in system. * * @return */ @@ -124,10 +115,8 @@ public interface KeycloakSession { */ UserProvider userStorageManager(); - UserCredentialManager userCredentialManager(); - /** - * A possibly cached view of all users in system that does NOT include users available from the deprecated UserFederationProvider SPI. + * A cached view of all users in system that does NOT include users available from the deprecated UserFederationProvider SPI. */ UserProvider userStorage(); @@ -140,7 +129,6 @@ public interface KeycloakSession { /** * Hybrid storage for UserStorageProviders that can't store a specific piece of keycloak data in their external storage. - * No cache in front. * * @return */ diff --git a/server-spi/src/main/java/org/keycloak/models/KeycloakTransactionManager.java b/server-spi/src/main/java/org/keycloak/models/KeycloakTransactionManager.java index a18d8cfd96..0e2dcbea97 100755 --- a/server-spi/src/main/java/org/keycloak/models/KeycloakTransactionManager.java +++ b/server-spi/src/main/java/org/keycloak/models/KeycloakTransactionManager.java @@ -23,21 +23,6 @@ package org.keycloak.models; */ public interface KeycloakTransactionManager extends KeycloakTransaction { - enum JTAPolicy { - /** - * Do not interact with JTA at all - * - */ - NOT_SUPPORTED, - /** - * A new JTA Transaction will be created when Keycloak TM begin() is called. If an existing JTA transaction - * exists, it is suspended and resumed after the Keycloak transaction finishes. - */ - REQUIRES_NEW, - } - - JTAPolicy getJTAPolicy(); - void setJTAPolicy(JTAPolicy policy); void enlist(KeycloakTransaction transaction); void enlistAfterCompletion(KeycloakTransaction transaction); diff --git a/server-spi/src/main/java/org/keycloak/models/UserCredentialManager.java b/server-spi/src/main/java/org/keycloak/models/UserCredentialManager.java deleted file mode 100644 index 2da5716f92..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/UserCredentialManager.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.models; - -import org.keycloak.credential.CredentialInput; -import org.keycloak.credential.UserCredentialStore; - -import java.util.List; -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface UserCredentialManager extends UserCredentialStore { - boolean isValid(RealmModel realm, UserModel user, List inputs); - - void updateCredential(RealmModel realm, UserModel user, CredentialInput input); - void disableCredential(RealmModel realm, UserModel user, String credentialType); - - boolean isConfiguredFor(RealmModel realm, UserModel user, String type); - -} diff --git a/server-spi/src/main/java/org/keycloak/models/UserCredentialModel.java b/server-spi/src/main/java/org/keycloak/models/UserCredentialModel.java index 4be355d19a..3e03508bda 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserCredentialModel.java +++ b/server-spi/src/main/java/org/keycloak/models/UserCredentialModel.java @@ -17,26 +17,23 @@ package org.keycloak.models; -import org.keycloak.credential.CredentialInput; -import org.keycloak.credential.CredentialModel; - import java.util.UUID; /** * @author Bill Burke * @version $Revision: 1 $ */ -public class UserCredentialModel implements CredentialInput { - public static final String PASSWORD = CredentialModel.PASSWORD; - public static final String PASSWORD_HISTORY = CredentialModel.PASSWORD_HISTORY; - public static final String PASSWORD_TOKEN = CredentialModel.PASSWORD_TOKEN; +public class UserCredentialModel { + public static final String PASSWORD = "password"; + public static final String PASSWORD_HISTORY = "password-history"; + public static final String PASSWORD_TOKEN = "password-token"; // Secret is same as password but it is not hashed - public static final String SECRET = CredentialModel.SECRET; - public static final String TOTP = CredentialModel.TOTP; - public static final String HOTP = CredentialModel.HOTP; - public static final String CLIENT_CERT = CredentialModel.CLIENT_CERT; - public static final String KERBEROS = CredentialModel.KERBEROS; + public static final String SECRET = "secret"; + public static final String TOTP = "totp"; + public static final String HOTP = "hotp"; + public static final String CLIENT_CERT = "cert"; + public static final String KERBEROS = "kerberos"; protected String type; protected String value; diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java b/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java index e1037053fc..cb6867ac57 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java +++ b/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java @@ -19,7 +19,6 @@ package org.keycloak.models; import org.jboss.logging.Logger; import org.keycloak.component.ComponentModel; -import org.keycloak.credential.CredentialInput; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.policy.PasswordPolicyManagerProvider; import org.keycloak.policy.PolicyError; diff --git a/server-spi/src/main/java/org/keycloak/models/UserProvider.java b/server-spi/src/main/java/org/keycloak/models/UserProvider.java index 642131b518..d6ef2cd360 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserProvider.java +++ b/server-spi/src/main/java/org/keycloak/models/UserProvider.java @@ -18,7 +18,6 @@ package org.keycloak.models; import org.keycloak.component.ComponentModel; -import org.keycloak.credential.CredentialInput; import org.keycloak.provider.Provider; import org.keycloak.storage.user.UserCredentialValidatorProvider; import org.keycloak.storage.user.UserLookupProvider; @@ -86,5 +85,4 @@ public interface UserProvider extends Provider, void close(); void preRemove(RealmModel realm, ComponentModel component); - } diff --git a/server-spi/src/main/java/org/keycloak/models/cache/OnUserCache.java b/server-spi/src/main/java/org/keycloak/models/cache/CacheUserProvider.java old mode 100644 new mode 100755 similarity index 85% rename from server-spi/src/main/java/org/keycloak/models/cache/OnUserCache.java rename to server-spi/src/main/java/org/keycloak/models/cache/CacheUserProvider.java index e676ce14e6..63c97061d6 --- a/server-spi/src/main/java/org/keycloak/models/cache/OnUserCache.java +++ b/server-spi/src/main/java/org/keycloak/models/cache/CacheUserProvider.java @@ -14,14 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.keycloak.models.cache; import org.keycloak.models.RealmModel; +import org.keycloak.models.UserProvider; /** * @author Bill Burke * @version $Revision: 1 $ */ -public interface OnUserCache { - void onCache(RealmModel realm, CachedUserModel user); +public interface CacheUserProvider extends UserProvider { + void clear(); + UserProvider getDelegate(); } diff --git a/server-spi/src/main/java/org/keycloak/models/cache/UserCacheProviderFactory.java b/server-spi/src/main/java/org/keycloak/models/cache/CacheUserProviderFactory.java similarity index 90% rename from server-spi/src/main/java/org/keycloak/models/cache/UserCacheProviderFactory.java rename to server-spi/src/main/java/org/keycloak/models/cache/CacheUserProviderFactory.java index fdf4fd881d..37208e4711 100755 --- a/server-spi/src/main/java/org/keycloak/models/cache/UserCacheProviderFactory.java +++ b/server-spi/src/main/java/org/keycloak/models/cache/CacheUserProviderFactory.java @@ -23,6 +23,6 @@ import org.keycloak.provider.ProviderFactory; * @author Bill Burke * @version $Revision: 1 $ */ -public interface UserCacheProviderFactory extends ProviderFactory { +public interface CacheUserProviderFactory extends ProviderFactory { } diff --git a/server-spi/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java b/server-spi/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java index a0efa39e91..c6723fba97 100755 --- a/server-spi/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java +++ b/server-spi/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java @@ -39,11 +39,11 @@ public class CacheUserProviderSpi implements Spi { @Override public Class getProviderClass() { - return UserCache.class; + return CacheUserProvider.class; } @Override public Class getProviderFactoryClass() { - return UserCacheProviderFactory.class; + return CacheUserProviderFactory.class; } } diff --git a/server-spi/src/main/java/org/keycloak/models/cache/CachedUserModel.java b/server-spi/src/main/java/org/keycloak/models/cache/CachedUserModel.java deleted file mode 100644 index 5d9c7cd278..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/cache/CachedUserModel.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.models.cache; - -import org.keycloak.models.UserModel; - -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface CachedUserModel extends UserModel { - void invalidate(); - - /** - * When was the user loaded from database. - * - * @return - */ - long getCacheTimestamp(); - - /** - * Returns a map that contains custom things that are cached along with the user. You can write to this map. - * - * @return - */ - ConcurrentHashMap getCachedWith(); -} diff --git a/server-spi/src/main/java/org/keycloak/models/cache/UserCache.java b/server-spi/src/main/java/org/keycloak/models/cache/UserCache.java deleted file mode 100755 index f309079d94..0000000000 --- a/server-spi/src/main/java/org/keycloak/models/cache/UserCache.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.models.cache; - -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.UserProvider; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface UserCache extends UserProvider { - /** - * Evict user from cache. - * - * @param user - */ - void evict(RealmModel realm, UserModel user); - void clear(); -} diff --git a/server-spi/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/server-spi/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java index b8adc6271d..bc20d49042 100755 --- a/server-spi/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java +++ b/server-spi/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java @@ -44,14 +44,8 @@ import org.keycloak.models.UserModel; import org.keycloak.representations.idm.CertificateRepresentation; import org.keycloak.common.util.CertificateUtils; import org.keycloak.common.util.PemUtils; -import org.keycloak.transaction.JtaTransactionManagerLookup; import javax.crypto.spec.SecretKeySpec; -import javax.naming.InitialContext; -import javax.sql.DataSource; -import javax.transaction.InvalidTransactionException; -import javax.transaction.SystemException; -import javax.transaction.Transaction; import java.io.IOException; import java.io.StringWriter; import java.security.Key; @@ -62,7 +56,6 @@ import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; -import java.sql.DriverManager; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -70,7 +63,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.function.Function; /** * Set of helper methods, which are useful in various model implementations. @@ -311,7 +303,6 @@ public final class KeycloakModelUtils { } } - public static String getMasterRealmAdminApplicationClientId(String realmName) { return realmName + "-realm"; } @@ -660,33 +651,4 @@ public final class KeycloakModelUtils { } } } - - public static void suspendJtaTransaction(KeycloakSessionFactory factory, Runnable runnable) { - JtaTransactionManagerLookup lookup = (JtaTransactionManagerLookup)factory.getProviderFactory(JtaTransactionManagerLookup.class); - Transaction suspended = null; - try { - if (lookup != null) { - if (lookup.getTransactionManager() != null) { - try { - suspended = lookup.getTransactionManager().suspend(); - } catch (SystemException e) { - throw new RuntimeException(e); - } - } - } - runnable.run(); - } finally { - if (suspended != null) { - try { - lookup.getTransactionManager().resume(suspended); - } catch (InvalidTransactionException e) { - throw new RuntimeException(e); - } catch (SystemException e) { - throw new RuntimeException(e); - } - } - - } - - } } diff --git a/services/src/main/java/org/keycloak/storage/UserStorageManager.java b/server-spi/src/main/java/org/keycloak/storage/UserStorageManager.java similarity index 90% rename from services/src/main/java/org/keycloak/storage/UserStorageManager.java rename to server-spi/src/main/java/org/keycloak/storage/UserStorageManager.java index e0b2ffd3c2..1a1fca543c 100755 --- a/services/src/main/java/org/keycloak/storage/UserStorageManager.java +++ b/server-spi/src/main/java/org/keycloak/storage/UserStorageManager.java @@ -30,8 +30,6 @@ import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; -import org.keycloak.models.cache.CachedUserModel; -import org.keycloak.models.cache.OnUserCache; import org.keycloak.storage.user.UserCredentialAuthenticationProvider; import org.keycloak.models.UserCredentialModel; import org.keycloak.storage.user.UserCredentialValidatorProvider; @@ -58,7 +56,7 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class UserStorageManager implements UserProvider, OnUserCache { +public class UserStorageManager implements UserProvider { private static final Logger logger = Logger.getLogger(UserStorageManager.class); @@ -72,22 +70,22 @@ public class UserStorageManager implements UserProvider, OnUserCache { return session.userLocalStorage(); } - public static List getStorageProviders(RealmModel realm) { + protected List getStorageProviders(RealmModel realm) { return realm.getUserStorageProviders(); } - public static T getFirstStorageProvider(KeycloakSession session, RealmModel realm, Class type) { + protected T getFirstStorageProvider(RealmModel realm, Class type) { for (UserStorageProviderModel model : getStorageProviders(realm)) { UserStorageProviderFactory factory = (UserStorageProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, model.getProviderId()); if (Types.supports(type, factory, UserStorageProviderFactory.class)) { - return type.cast(getStorageProviderInstance(session, model, factory)); + return type.cast(getStorageProviderInstance(model, factory)); } } return null; } - public static UserStorageProvider getStorageProviderInstance(KeycloakSession session, UserStorageProviderModel model, UserStorageProviderFactory factory) { + private UserStorageProvider getStorageProviderInstance(UserStorageProviderModel model, UserStorageProviderFactory factory) { UserStorageProvider instance = (UserStorageProvider)session.getAttribute(model.getId()); if (instance != null) return instance; instance = factory.create(session, model); @@ -97,12 +95,12 @@ public class UserStorageManager implements UserProvider, OnUserCache { } - public static List getStorageProviders(KeycloakSession session, RealmModel realm, Class type) { + protected List getStorageProviders(RealmModel realm, Class type) { List list = new LinkedList<>(); for (UserStorageProviderModel model : getStorageProviders(realm)) { UserStorageProviderFactory factory = (UserStorageProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, model.getProviderId()); if (Types.supports(type, factory, UserStorageProviderFactory.class)) { - list.add(type.cast(getStorageProviderInstance(session, model, factory))); + list.add(type.cast(getStorageProviderInstance(model, factory))); } @@ -118,21 +116,21 @@ public class UserStorageManager implements UserProvider, OnUserCache { @Override public UserModel addUser(RealmModel realm, String username) { - UserRegistrationProvider registry = getFirstStorageProvider(session, realm, UserRegistrationProvider.class); + UserRegistrationProvider registry = getFirstStorageProvider(realm, UserRegistrationProvider.class); if (registry != null) { return registry.addUser(realm, username); } return localStorage().addUser(realm, username.toLowerCase()); } - public static UserStorageProvider getStorageProvider(KeycloakSession session, RealmModel realm, String componentId) { + public UserStorageProvider getStorageProvider(RealmModel realm, String componentId) { ComponentModel model = realm.getComponent(componentId); if (model == null) return null; UserStorageProviderFactory factory = (UserStorageProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, model.getProviderId()); if (factory == null) { throw new ModelException("Could not find UserStorageProviderFactory for: " + model.getProviderId()); } - return getStorageProviderInstance(session, new UserStorageProviderModel(model), factory); + return getStorageProviderInstance(new UserStorageProviderModel(model), factory); } @Override @@ -142,7 +140,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { if (storageId.getProviderId() == null) { return localStorage().removeUser(realm, user); } - UserRegistrationProvider registry = (UserRegistrationProvider)getStorageProvider(session, realm, storageId.getProviderId()); + UserRegistrationProvider registry = (UserRegistrationProvider)getStorageProvider(realm, storageId.getProviderId()); if (registry == null) { throw new ModelException("Could not resolve StorageProvider: " + storageId.getProviderId()); } @@ -235,7 +233,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { if (storageId.getProviderId() == null) { return localStorage().getUserById(id, realm); } - UserLookupProvider provider = (UserLookupProvider)getStorageProvider(session, realm, storageId.getProviderId()); + UserLookupProvider provider = (UserLookupProvider)getStorageProvider(realm, storageId.getProviderId()); return provider.getUserById(id, realm); } @@ -248,7 +246,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { public UserModel getUserByUsername(String username, RealmModel realm) { UserModel user = localStorage().getUserByUsername(username, realm); if (user != null) return user; - for (UserLookupProvider provider : getStorageProviders(session, realm, UserLookupProvider.class)) { + for (UserLookupProvider provider : getStorageProviders(realm, UserLookupProvider.class)) { user = provider.getUserByUsername(username, realm); if (user != null) return user; } @@ -259,7 +257,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { public UserModel getUserByEmail(String email, RealmModel realm) { UserModel user = localStorage().getUserByEmail(email, realm); if (user != null) return user; - for (UserLookupProvider provider : getStorageProviders(session, realm, UserLookupProvider.class)) { + for (UserLookupProvider provider : getStorageProviders(realm, UserLookupProvider.class)) { user = provider.getUserByEmail(email, realm); if (user != null) return user; } @@ -301,7 +299,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { @Override public int getUsersCount(RealmModel realm) { int size = localStorage().getUsersCount(realm); - for (UserQueryProvider provider : getStorageProviders(session, realm, UserQueryProvider.class)) { + for (UserQueryProvider provider : getStorageProviders(realm, UserQueryProvider.class)) { size += provider.getUsersCount(realm); } return size; @@ -317,7 +315,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { - List storageProviders = getStorageProviders(session, realm, UserQueryProvider.class); + List storageProviders = getStorageProviders(realm, UserQueryProvider.class); // we can skip rest of method if there are no storage providers if (storageProviders.isEmpty()) { return pagedQuery.query(localStorage(), firstResult, maxResults); @@ -449,7 +447,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { @Override public void grantToAllUsers(RealmModel realm, RoleModel role) { // not federation-aware for now - List storageProviders = getStorageProviders(session, realm, UserRegistrationProvider.class); + List storageProviders = getStorageProviders(realm, UserRegistrationProvider.class); LinkedList providers = new LinkedList<>(); providers.add(localStorage()); providers.addAll(storageProviders); @@ -484,7 +482,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { public void preRemove(RealmModel realm) { localStorage().preRemove(realm); getFederatedStorage().preRemove(realm); - for (UserStorageProvider provider : getStorageProviders(session, realm, UserStorageProvider.class)) { + for (UserStorageProvider provider : getStorageProviders(realm, UserStorageProvider.class)) { provider.preRemove(realm); } } @@ -499,7 +497,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { public void preRemove(RealmModel realm, GroupModel group) { localStorage().preRemove(realm, group); getFederatedStorage().preRemove(realm, group); - for (UserStorageProvider provider : getStorageProviders(session, realm, UserStorageProvider.class)) { + for (UserStorageProvider provider : getStorageProviders(realm, UserStorageProvider.class)) { provider.preRemove(realm, group); } } @@ -508,7 +506,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { public void preRemove(RealmModel realm, RoleModel role) { localStorage().preRemove(realm, role); getFederatedStorage().preRemove(realm, role); - for (UserStorageProvider provider : getStorageProviders(session, realm, UserStorageProvider.class)) { + for (UserStorageProvider provider : getStorageProviders(realm, UserStorageProvider.class)) { provider.preRemove(realm, role); } } @@ -560,7 +558,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { if (toValidate.isEmpty()) return true; - UserStorageProvider provider = getStorageProvider(session, realm, StorageId.resolveProviderId(user)); + UserStorageProvider provider = getStorageProvider(realm, StorageId.resolveProviderId(user)); if (!(provider instanceof UserCredentialValidatorProvider)) { return false; } @@ -574,7 +572,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { @Override public CredentialValidationOutput validCredentials(KeycloakSession session, RealmModel realm, UserCredentialModel... input) { - List providers = getStorageProviders(session, realm, UserCredentialAuthenticationProvider.class); + List providers = getStorageProviders(realm, UserCredentialAuthenticationProvider.class); if (providers.isEmpty()) return CredentialValidationOutput.failed(); CredentialValidationOutput result = null; @@ -608,23 +606,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { } - @Override - public void onCache(RealmModel realm, CachedUserModel user) { - if (StorageId.isLocalStorage(user)) { - if (session.userLocalStorage() instanceof OnUserCache) { - ((OnUserCache)session.userLocalStorage()).onCache(realm, user); - } - } else { - Object provider = getStorageProvider(session, realm, StorageId.resolveProviderId(user)); - if (provider != null && provider instanceof OnUserCache) { - ((OnUserCache)provider).onCache(realm, user); - } - } - } - @Override public void close() { } - - } diff --git a/server-spi/src/main/java/org/keycloak/storage/UserStorageProviderModel.java b/server-spi/src/main/java/org/keycloak/storage/UserStorageProviderModel.java index 42ad397ce0..351107f94f 100755 --- a/server-spi/src/main/java/org/keycloak/storage/UserStorageProviderModel.java +++ b/server-spi/src/main/java/org/keycloak/storage/UserStorageProviderModel.java @@ -17,8 +17,14 @@ package org.keycloak.storage; +import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.component.ComponentModel; -import org.keycloak.component.PrioritizedComponentModel; +import org.keycloak.models.RealmModel; + +import java.io.Serializable; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; /** * Stored configuration of a User Storage provider instance. @@ -26,7 +32,14 @@ import org.keycloak.component.PrioritizedComponentModel; * @author Marek Posolda * @author Bill Burke */ -public class UserStorageProviderModel extends PrioritizedComponentModel { +public class UserStorageProviderModel extends ComponentModel { + + public static Comparator comparator = new Comparator() { + @Override + public int compare(UserStorageProviderModel o1, UserStorageProviderModel o2) { + return o1.getPriority() - o2.getPriority(); + } + }; public UserStorageProviderModel() { setProviderType(UserStorageProvider.class.getName()); @@ -36,4 +49,14 @@ public class UserStorageProviderModel extends PrioritizedComponentModel { super(copy); } + public int getPriority() { + String priority = getConfig().getFirst("priority"); + if (priority == null) return 0; + return Integer.valueOf(priority); + + } + + public void setPriority(int priority) { + getConfig().putSingle("priority", Integer.toString(priority)); + } } diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserCredentialsFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserCredentialsFederatedStorage.java index 2202f628ef..7239182877 100644 --- a/server-spi/src/main/java/org/keycloak/storage/federated/UserCredentialsFederatedStorage.java +++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserCredentialsFederatedStorage.java @@ -16,7 +16,6 @@ */ package org.keycloak.storage.federated; -import org.keycloak.credential.CredentialModel; import org.keycloak.models.RealmModel; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialValueModel; @@ -29,20 +28,8 @@ import java.util.List; * @version $Revision: 1 $ */ public interface UserCredentialsFederatedStorage { - // deprecated void updateCredential(RealmModel realm, UserModel user, UserCredentialModel cred); void updateCredential(RealmModel realm, UserModel user, UserCredentialValueModel cred); void removeCredential(RealmModel realm, UserModel user, UserCredentialValueModel cred); List getCredentials(RealmModel realm, UserModel user); - - // new - void updateCredential(RealmModel realm, UserModel user, CredentialModel cred); - CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred); - boolean removeCredential(RealmModel realm, String id); - CredentialModel getCredentialById(String id); - List getCredentials(RealmModel realm); - List getUserCredentials(RealmModel realm, UserModel user); - List getCredentialsByType(RealmModel realm, UserModel user, String type); - CredentialModel getCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type); - } diff --git a/server-spi/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/server-spi/src/main/resources/META-INF/services/org.keycloak.provider.Spi index 5ab0346aa3..d2431d84b0 100755 --- a/server-spi/src/main/resources/META-INF/services/org.keycloak.provider.Spi +++ b/server-spi/src/main/resources/META-INF/services/org.keycloak.provider.Spi @@ -61,5 +61,4 @@ org.keycloak.authorization.AuthorizationSpi org.keycloak.models.cache.authorization.CachedStoreFactorySpi org.keycloak.protocol.oidc.TokenIntrospectionSpi org.keycloak.policy.PasswordPolicySpi -org.keycloak.policy.PasswordPolicyManagerSpi -org.keycloak.transaction.TransactionManagerLookupSpi +org.keycloak.policy.PasswordPolicyManagerSpi \ No newline at end of file diff --git a/services/src/main/java/org/keycloak/credential/LocalOTPCredentialManager.java b/services/src/main/java/org/keycloak/credential/LocalOTPCredentialManager.java deleted file mode 100644 index 6d9baf0345..0000000000 --- a/services/src/main/java/org/keycloak/credential/LocalOTPCredentialManager.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.credential; - -import org.jboss.logging.Logger; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.OTPPolicy; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.cache.CachedUserModel; -import org.keycloak.models.cache.OnUserCache; -import org.keycloak.models.utils.HmacOTP; -import org.keycloak.models.utils.TimeBasedOTP; - -import java.util.Collections; -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class LocalOTPCredentialManager implements CredentialInputValidator, CredentialInputUpdater, OnUserCache { - private static final Logger logger = Logger.getLogger(LocalOTPCredentialManager.class); - - protected KeycloakSession session; - - protected List getCachedCredentials(UserModel user, String type) { - if (!(user instanceof CachedUserModel)) return Collections.EMPTY_LIST; - CachedUserModel cached = (CachedUserModel)user; - List rtn = (List)cached.getCachedWith().get(LocalOTPCredentialManager.class.getName() + "." + type); - if (rtn == null) return Collections.EMPTY_LIST; - return rtn; - } - - protected UserCredentialStore getCredentialStore() { - return session.userCredentialManager(); - } - - @Override - public void onCache(RealmModel realm, CachedUserModel user) { - List creds = getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP); - user.getCachedWith().put(LocalOTPCredentialManager.class.getName() + "." + CredentialModel.TOTP, creds); - - } - - public LocalOTPCredentialManager(KeycloakSession session) { - this.session = session; - } - - @Override - public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) { - if (!supportsCredentialType(input.getType())) return false; - - if (!(input instanceof UserCredentialModel)) { - logger.debug("Expected instance of UserCredentialModel for CredentialInput"); - return false; - } - UserCredentialModel inputModel = (UserCredentialModel)input; - CredentialModel model = null; - if (inputModel.getDevice() != null) { - model = getCredentialStore().getStoredCredentialByNameAndType(realm, user, inputModel.getDevice(), CredentialModel.TOTP); - if (model == null) { - model = getCredentialStore().getStoredCredentialByNameAndType(realm, user, inputModel.getDevice(), CredentialModel.HOTP); - } - } - if (model == null) { - // delete all existing - disableCredentialType(realm, user, CredentialModel.OTP); - model = new CredentialModel(); - } - - OTPPolicy policy = realm.getOTPPolicy(); - model.setDigits(policy.getDigits()); - model.setCounter(policy.getInitialCounter()); - model.setAlgorithm(policy.getAlgorithm()); - model.setType(policy.getType()); - model.setValue(inputModel.getValue()); - model.setDevice(inputModel.getDevice()); - model.setPeriod(policy.getPeriod()); - if (model.getId() == null) { - getCredentialStore().createCredential(realm, user, model); - } else { - getCredentialStore().updateCredential(realm, user, model); - } - session.getUserCache().evict(realm, user); - return true; - - - - } - - @Override - public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) { - boolean disableTOTP = false, disableHOTP = false; - if (CredentialModel.OTP.equals(credentialType)) { - disableTOTP = true; - disableHOTP = true; - } else if (CredentialModel.HOTP.equals(credentialType)) { - disableHOTP = true; - - } else if (CredentialModel.TOTP.equals(credentialType)) { - disableTOTP = true; - } - if (disableHOTP) { - List hotp = getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.HOTP); - for (CredentialModel cred : hotp) { - getCredentialStore().removeStoredCredential(realm, user, cred.getId()); - } - - } - if (disableTOTP) { - List totp = getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP); - if (!totp.isEmpty()) { - for (CredentialModel cred : totp) { - getCredentialStore().removeStoredCredential(realm, user, cred.getId()); - } - } - - } - if (disableTOTP || disableHOTP) { - session.getUserCache().evict(realm, user); - } - } - - @Override - public boolean supportsCredentialType(String credentialType) { - return CredentialModel.OTP.equals(credentialType) - || CredentialModel.HOTP.equals(credentialType) - || CredentialModel.TOTP.equals(credentialType); - } - - @Override - public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) { - if (!supportsCredentialType(credentialType)) return false; - if (CredentialModel.OTP.equals(credentialType)) { - if (realm.getOTPPolicy().getType().equals(CredentialModel.HOTP)) { - return configuredForHOTP(realm, user); - } else { - return configuredForTOTP(realm, user); - } - } else if (CredentialModel.HOTP.equals(credentialType)) { - return configuredForHOTP(realm, user); - - } else if (CredentialModel.TOTP.equals(credentialType)) { - return configuredForTOTP(realm, user); - } else { - return false; - } - - } - - protected boolean configuredForHOTP(RealmModel realm, UserModel user) { - return !getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.HOTP).isEmpty(); - } - - protected boolean configuredForTOTP(RealmModel realm, UserModel user) { - return !getCachedCredentials(user, CredentialModel.TOTP).isEmpty() - || !getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP).isEmpty(); - } - - public static boolean validOTP(RealmModel realm, String token, String secret) { - OTPPolicy policy = realm.getOTPPolicy(); - if (policy.getType().equals(UserCredentialModel.TOTP)) { - TimeBasedOTP validator = new TimeBasedOTP(policy.getAlgorithm(), policy.getDigits(), policy.getPeriod(), policy.getLookAheadWindow()); - return validator.validateTOTP(token, secret.getBytes()); - } else { - HmacOTP validator = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow()); - int c = validator.validateHOTP(token, secret, policy.getInitialCounter()); - return c > -1; - } - - } - - @Override - public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) { - if (! (input instanceof UserCredentialModel)) { - logger.debug("Expected instance of UserCredentialModel for CredentialInput"); - return false; - - } - String token = ((UserCredentialModel)input).getValue(); - OTPPolicy policy = realm.getOTPPolicy(); - if (realm.getOTPPolicy().getType().equals(CredentialModel.HOTP)) { - HmacOTP validator = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow()); - for (CredentialModel cred : getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.HOTP)) { - int counter = validator.validateHOTP(token, cred.getValue(), cred.getCounter()); - if (counter < 0) continue; - cred.setCounter(counter); - getCredentialStore().updateCredential(realm, user, cred); - return true; - } - } else { - TimeBasedOTP validator = new TimeBasedOTP(policy.getAlgorithm(), policy.getDigits(), policy.getPeriod(), policy.getLookAheadWindow()); - List creds = getCachedCredentials(user, CredentialModel.TOTP); - if (creds.isEmpty()) { - creds = getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP); - } else { - logger.debugv("Cache hit for TOTP for user {0}", user.getUsername()); - } - for (CredentialModel cred : creds) { - if (validator.validateTOTP(token, cred.getValue().getBytes())) { - return true; - } - } - - } - return false; - } -} diff --git a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java deleted file mode 100644 index 5f67768378..0000000000 --- a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.credential; - -import org.keycloak.common.util.reflections.Types; -import org.keycloak.component.ComponentModel; -import org.keycloak.component.PrioritizedComponentModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserCredentialManager; -import org.keycloak.models.UserModel; -import org.keycloak.models.cache.CachedUserModel; -import org.keycloak.models.cache.OnUserCache; -import org.keycloak.storage.StorageId; -import org.keycloak.storage.UserStorageManager; -import org.keycloak.storage.UserStorageProvider; - -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class UserCredentialStoreManager implements UserCredentialManager, OnUserCache { - protected KeycloakSession session; - - public UserCredentialStoreManager(KeycloakSession session) { - this.session = session; - } - - protected UserCredentialStore getStoreForUser(UserModel user) { - if (StorageId.isLocalStorage(user)) { - return (UserCredentialStore)session.userLocalStorage(); - } else { - return (UserCredentialStore)session.userFederatedStorage(); - } - } - - @Override - public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) { - getStoreForUser(user).updateCredential(realm, user, cred); - - } - - @Override - public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) { - return getStoreForUser(user).createCredential(realm, user, cred); - } - - @Override - public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) { - return getStoreForUser(user).removeStoredCredential(realm, user, id); - } - - @Override - public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) { - return getStoreForUser(user).getStoredCredentialById(realm, user, id); - } - - @Override - public List getStoredCredentials(RealmModel realm, UserModel user) { - return getStoreForUser(user).getStoredCredentials(realm, user); - } - - @Override - public List getStoredCredentialsByType(RealmModel realm, UserModel user, String type) { - return getStoreForUser(user).getStoredCredentialsByType(realm, user, type); - } - - @Override - public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) { - return getStoreForUser(user).getStoredCredentialByNameAndType(realm, user, name, type); - } - - - @Override - public boolean isValid(RealmModel realm, UserModel user, List inputs) { - - List toValidate = new LinkedList<>(); - toValidate.addAll(inputs); - if (!StorageId.isLocalStorage(user)) { - String providerId = StorageId.resolveProviderId(user); - UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, providerId); - if (provider instanceof CredentialInputValidator) { - Iterator it = toValidate.iterator(); - while (it.hasNext()) { - CredentialInput input = it.next(); - CredentialInputValidator validator = (CredentialInputValidator)provider; - if (validator.supportsCredentialType(input.getType()) && validator.isValid(realm, user, input)) { - it.remove(); - } - } - } - } - - if (toValidate.isEmpty()) return true; - - List components = getCredentialProviderComponents(realm); - for (ComponentModel component : components) { - CredentialProviderFactory factory = (CredentialProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(CredentialProvider.class, component.getProviderId()); - if (!Types.supports(CredentialInputValidator.class, factory, CredentialProviderFactory.class)) continue; - Iterator it = toValidate.iterator(); - while (it.hasNext()) { - CredentialInput input = it.next(); - CredentialInputValidator validator = (CredentialInputValidator)session.getAttribute(component.getId()); - if (validator == null) { - validator = (CredentialInputValidator)factory.create(session, component); - session.setAttribute(component.getId(), validator); - } - if (validator.supportsCredentialType(input.getType()) && validator.isValid(realm, user, input)) { - it.remove(); - } - } - } - - return toValidate.isEmpty(); - } - - protected List getCredentialProviderComponents(RealmModel realm) { - List components = realm.getComponents(realm.getId(), CredentialProvider.class.getName()); - if (components.isEmpty()) return components; - List copy = new LinkedList<>(); - copy.addAll(components); - Collections.sort(copy, PrioritizedComponentModel.comparator); - return copy; - } - - @Override - public void updateCredential(RealmModel realm, UserModel user, CredentialInput input) { - if (!StorageId.isLocalStorage(user)) { - String providerId = StorageId.resolveProviderId(user); - UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, providerId); - if (provider instanceof CredentialInputUpdater) { - CredentialInputUpdater updater = (CredentialInputUpdater)provider; - if (updater.supportsCredentialType(input.getType())) { - if (updater.updateCredential(realm, user, input)) return; - } - } - } - - List components = getCredentialProviderComponents(realm); - for (ComponentModel component : components) { - CredentialProviderFactory factory = (CredentialProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(CredentialProvider.class, component.getProviderId()); - if (!Types.supports(CredentialInputUpdater.class, factory, CredentialProviderFactory.class)) continue; - CredentialInputUpdater updater = (CredentialInputUpdater)session.getAttribute(component.getId()); - if (updater == null) { - updater = (CredentialInputUpdater)factory.create(session, component); - session.setAttribute(component.getId(), updater); - } - if (!updater.supportsCredentialType(input.getType())) continue; - if (updater.updateCredential(realm, user, input)) return; - } - - } - @Override - public void disableCredential(RealmModel realm, UserModel user, String credentialType) { - if (!StorageId.isLocalStorage(user)) { - String providerId = StorageId.resolveProviderId(user); - UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, providerId); - if (provider instanceof CredentialInputUpdater) { - CredentialInputUpdater updater = (CredentialInputUpdater)provider; - if (updater.supportsCredentialType(credentialType)) { - updater.disableCredentialType(realm, user, credentialType); - } - } - } - - List components = getCredentialProviderComponents(realm); - for (ComponentModel component : components) { - CredentialProviderFactory factory = (CredentialProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(CredentialProvider.class, component.getProviderId()); - if (!Types.supports(CredentialInputUpdater.class, factory, CredentialProviderFactory.class)) continue; - CredentialInputUpdater updater = (CredentialInputUpdater)session.getAttribute(component.getId()); - if (updater == null) { - updater = (CredentialInputUpdater)factory.create(session, component); - session.setAttribute(component.getId(), updater); - } - if (!updater.supportsCredentialType(credentialType)) continue; - updater.disableCredentialType(realm, user, credentialType); - } - - } - @Override - public boolean isConfiguredFor(RealmModel realm, UserModel user, String type) { - if (!StorageId.isLocalStorage(user)) { - String providerId = StorageId.resolveProviderId(user); - UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, providerId); - if (provider instanceof CredentialInputValidator) { - CredentialInputValidator validator = (CredentialInputValidator)provider; - if (validator.supportsCredentialType(type) && validator.isConfiguredFor(realm, user, type)) { - return true; - } - } - } - - List components = getCredentialProviderComponents(realm); - for (ComponentModel component : components) { - CredentialProviderFactory factory = (CredentialProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(CredentialProvider.class, component.getProviderId()); - if (!Types.supports(CredentialInputUpdater.class, factory, CredentialProviderFactory.class)) continue; - CredentialInputValidator validator = (CredentialInputValidator)session.getAttribute(component.getId()); - if (validator == null) { - validator = (CredentialInputValidator)factory.create(session, component); - session.setAttribute(component.getId(), validator); - } - if (validator.supportsCredentialType(type) && validator.isConfiguredFor(realm, user, type)) { - return true; - } - } - return false; - - } - - @Override - public void onCache(RealmModel realm, CachedUserModel user) { - List components = getCredentialProviderComponents(realm); - for (ComponentModel component : components) { - CredentialProviderFactory factory = (CredentialProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(CredentialProvider.class, component.getProviderId()); - if (!Types.supports(OnUserCache.class, factory, CredentialProviderFactory.class)) continue; - OnUserCache validator = (OnUserCache)session.getAttribute(component.getId()); - if (validator == null) { - validator = (OnUserCache)factory.create(session, component); - session.setAttribute(component.getId(), validator); - } - validator.onCache(realm, user); - } - - } - - @Override - public void close() { - - } -} diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java index b1ae4ddac1..1fae787117 100644 --- a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java +++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java @@ -16,18 +16,15 @@ */ package org.keycloak.services; -import org.keycloak.credential.UserCredentialStore; -import org.keycloak.credential.UserCredentialStoreManager; import org.keycloak.models.*; import org.keycloak.models.cache.CacheRealmProvider; -import org.keycloak.models.cache.UserCache; +import org.keycloak.models.cache.CacheUserProvider; import org.keycloak.provider.Provider; import org.keycloak.provider.ProviderFactory; import org.keycloak.scripting.ScriptingProvider; import org.keycloak.storage.UserStorageManager; import org.keycloak.storage.federated.UserFederatedStorageProvider; -import javax.transaction.TransactionManager; import java.util.*; /** @@ -43,7 +40,6 @@ public class DefaultKeycloakSession implements KeycloakSession { private RealmProvider model; private UserProvider userModel; private UserStorageManager userStorageManager; - private UserCredentialStoreManager userCredentialStorageManager; private ScriptingProvider scriptingProvider; private UserSessionProvider sessionProvider; private UserFederationManager federationManager; @@ -52,7 +48,7 @@ public class DefaultKeycloakSession implements KeycloakSession { public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) { this.factory = factory; - this.transactionManager = new DefaultKeycloakTransactionManager(this); + this.transactionManager = new DefaultKeycloakTransactionManager(); federationManager = new UserFederationManager(this); context = new DefaultKeycloakContext(this); } @@ -72,7 +68,7 @@ public class DefaultKeycloakSession implements KeycloakSession { } private UserProvider getUserProvider() { - UserCache cache = getProvider(UserCache.class); + CacheUserProvider cache = getProvider(CacheUserProvider.class); if (cache != null) { return cache; } else { @@ -80,12 +76,6 @@ public class DefaultKeycloakSession implements KeycloakSession { } } - @Override - public UserCache getUserCache() { - return getProvider(UserCache.class); - - } - @Override public void enlistForClose(Provider provider) { closable.add(provider); @@ -135,12 +125,6 @@ public class DefaultKeycloakSession implements KeycloakSession { return userStorageManager; } - @Override - public UserCredentialManager userCredentialManager() { - if (userCredentialStorageManager == null) userCredentialStorageManager = new UserCredentialStoreManager(this); - return userCredentialStorageManager; - } - @Override public UserProvider userStorage() { if (userModel == null) { diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakSessionFactory.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakSessionFactory.java index d5474dcb69..45bef3c3ea 100755 --- a/services/src/main/java/org/keycloak/services/DefaultKeycloakSessionFactory.java +++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakSessionFactory.java @@ -49,6 +49,7 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory, Pr private Map, String> provider = new HashMap<>(); private volatile Map, Map> factoriesMap = new HashMap<>(); protected CopyOnWriteArrayList listeners = new CopyOnWriteArrayList<>(); + private TransactionManager tm; // TODO: Likely should be changed to int and use Time.currentTime() to be compatible with all our "time" reps protected long serverStartupTimestamp; @@ -96,6 +97,8 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory, Pr // make the session factory ready for hot deployment ProviderManagerRegistry.SINGLETON.setDeployer(this); + JtaTransactionManagerLookup lookup = (JtaTransactionManagerLookup)getProviderFactory(JtaTransactionManagerLookup.class); + if (lookup != null) tm = lookup.getTransactionManager(); } protected Map, Map> getFactoriesCopy() { Map, Map> copy = new HashMap<>(); @@ -279,6 +282,9 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory, Pr public KeycloakSession create() { KeycloakSession session = new DefaultKeycloakSession(this); + if (tm != null) { + session.getTransactionManager().enlist(new JtaTransactionWrapper(tm)); + } return session; } diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakTransactionManager.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakTransactionManager.java index 81379a1cdf..53f92f4fb8 100755 --- a/services/src/main/java/org/keycloak/services/DefaultKeycloakTransactionManager.java +++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakTransactionManager.java @@ -16,13 +16,9 @@ */ package org.keycloak.services; -import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakTransaction; import org.keycloak.models.KeycloakTransactionManager; -import org.keycloak.transaction.JtaTransactionManagerLookup; -import org.keycloak.transaction.JtaTransactionWrapper; -import javax.transaction.TransactionManager; import java.util.LinkedList; import java.util.List; @@ -38,12 +34,6 @@ public class DefaultKeycloakTransactionManager implements KeycloakTransactionMan private List afterCompletion = new LinkedList(); private boolean active; private boolean rollback; - private KeycloakSession session; - private JTAPolicy jtaPolicy = JTAPolicy.REQUIRES_NEW; - - public DefaultKeycloakTransactionManager(KeycloakSession session) { - this.session = session; - } @Override public void enlist(KeycloakTransaction transaction) { @@ -72,31 +62,12 @@ public class DefaultKeycloakTransactionManager implements KeycloakTransactionMan prepare.add(transaction); } - @Override - public JTAPolicy getJTAPolicy() { - return jtaPolicy; - } - - @Override - public void setJTAPolicy(JTAPolicy policy) { - jtaPolicy = policy; - - } - @Override public void begin() { if (active) { throw new IllegalStateException("Transaction already active"); } - if (jtaPolicy == JTAPolicy.REQUIRES_NEW) { - JtaTransactionManagerLookup jtaLookup = session.getProvider(JtaTransactionManagerLookup.class); - TransactionManager tm = jtaLookup.getTransactionManager(); - if (tm != null) { - enlist(new JtaTransactionWrapper(tm)); - } - } - for (KeycloakTransaction tx : transactions) { tx.begin(); } 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 68e080663b..6cdf52eab2 100644 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -45,13 +45,10 @@ import org.keycloak.services.scheduled.ClusterAwareScheduledTaskRunner; import org.keycloak.services.util.JsonConfigProvider; import org.keycloak.services.util.ObjectMapperResolver; import org.keycloak.timer.TimerProvider; -import org.keycloak.transaction.JtaTransactionManagerLookup; import org.keycloak.util.JsonSerialization; import org.keycloak.common.util.SystemEnvProperties; import javax.servlet.ServletContext; -import javax.transaction.SystemException; -import javax.transaction.Transaction; import javax.ws.rs.core.Application; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; @@ -158,28 +155,11 @@ public class KeycloakApplication extends Application { // Migrate model, bootstrap master realm, import realms and create admin user. This is done with acquired dbLock protected ExportImportManager migrateAndBootstrap() { ExportImportManager exportImportManager; - logger.debug("Calling migrateModel"); migrateModel(); - logger.debug("bootstrap"); KeycloakSession session = sessionFactory.create(); try { session.getTransactionManager().begin(); - JtaTransactionManagerLookup lookup = (JtaTransactionManagerLookup) sessionFactory.getProviderFactory(JtaTransactionManagerLookup.class); - if (lookup != null) { - if (lookup.getTransactionManager() != null) { - try { - Transaction transaction = lookup.getTransactionManager().getTransaction(); - logger.debugv("bootstrap current transaction? {0}", transaction != null); - if (transaction != null) { - logger.debugv("bootstrap current transaction status? {0}", transaction.getStatus()); - } - } catch (SystemException e) { - throw new RuntimeException(e); - } - } - } - ApplianceBootstrap applianceBootstrap = new ApplianceBootstrap(session); exportImportManager = new ExportImportManager(session); 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 7d4922340d..4fd941b728 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -34,6 +34,8 @@ import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; import org.keycloak.exportimport.ClientDescriptionConverter; import org.keycloak.exportimport.ClientDescriptionConverterFactory; +import org.keycloak.jose.jws.JWSBuilder; +import org.keycloak.jose.jws.JWSInput; import org.keycloak.models.ClientModel; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; @@ -42,7 +44,7 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserSessionModel; import org.keycloak.models.cache.CacheRealmProvider; -import org.keycloak.models.cache.UserCache; +import org.keycloak.models.cache.CacheUserProvider; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; @@ -53,6 +55,7 @@ import org.keycloak.representations.idm.AdminEventRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.GroupRepresentation; +import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.PartialImportRepresentation; import org.keycloak.representations.idm.RealmEventsConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; @@ -64,6 +67,7 @@ import org.keycloak.services.ServicesLogger; import org.keycloak.services.managers.UsersSyncManager; import org.keycloak.services.ErrorResponse; import org.keycloak.services.resources.admin.RealmAuth.Resource; +import org.keycloak.timer.TimerProvider; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -81,6 +85,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; +import java.security.PrivateKey; +import java.security.PublicKey; import java.security.cert.X509Certificate; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -860,7 +866,7 @@ public class RealmAdminResource { public void clearUserCache() { auth.requireManage(); - UserCache cache = session.getProvider(UserCache.class); + CacheUserProvider cache = session.getProvider(CacheUserProvider.class); if (cache != null) { cache.clear(); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index 26daf84019..3986988f87 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -184,8 +184,6 @@ public class UsersResource { return ErrorResponse.exists("User is read only!"); } catch (ModelException me) { return ErrorResponse.exists("Could not update user!"); - } catch (Exception me) { // JPA may be committed by JTA which can't - return ErrorResponse.exists("Could not update user!"); } } diff --git a/server-spi/src/main/java/org/keycloak/transaction/JtaTransactionManagerLookup.java b/services/src/main/java/org/keycloak/transaction/JtaTransactionManagerLookup.java similarity index 100% rename from server-spi/src/main/java/org/keycloak/transaction/JtaTransactionManagerLookup.java rename to services/src/main/java/org/keycloak/transaction/JtaTransactionManagerLookup.java diff --git a/services/src/main/java/org/keycloak/transaction/JtaTransactionWrapper.java b/services/src/main/java/org/keycloak/transaction/JtaTransactionWrapper.java index e387ff4599..ecc3071a0d 100644 --- a/services/src/main/java/org/keycloak/transaction/JtaTransactionWrapper.java +++ b/services/src/main/java/org/keycloak/transaction/JtaTransactionWrapper.java @@ -16,9 +16,7 @@ */ package org.keycloak.transaction; -import org.jboss.logging.Logger; import org.keycloak.models.KeycloakTransaction; -import org.keycloak.storage.UserStorageManager; import javax.transaction.InvalidTransactionException; import javax.transaction.NotSupportedException; @@ -33,22 +31,16 @@ import javax.transaction.UserTransaction; * @version $Revision: 1 $ */ public class JtaTransactionWrapper implements KeycloakTransaction { - private static final Logger logger = Logger.getLogger(JtaTransactionWrapper.class); protected TransactionManager tm; protected Transaction ut; protected Transaction suspended; - protected Exception ended; public JtaTransactionWrapper(TransactionManager tm) { this.tm = tm; try { - suspended = tm.suspend(); - logger.debug("new JtaTransactionWrapper"); - logger.debugv("was existing? {0}", suspended != null); tm.begin(); ut = tm.getTransaction(); - //ended = new Exception(); } catch (Exception e) { throw new RuntimeException(e); } @@ -61,20 +53,16 @@ public class JtaTransactionWrapper implements KeycloakTransaction { @Override public void commit() { try { - logger.debug("JtaTransactionWrapper commit"); - tm.commit(); + ut.commit(); } catch (Exception e) { throw new RuntimeException(e); - } finally { - end(); } } @Override public void rollback() { try { - logger.debug("JtaTransactionWrapper rollback"); - tm.rollback(); + ut.rollback(); } catch (Exception e) { throw new RuntimeException(e); } finally { @@ -86,7 +74,7 @@ public class JtaTransactionWrapper implements KeycloakTransaction { @Override public void setRollbackOnly() { try { - tm.setRollbackOnly(); + ut.setRollbackOnly(); } catch (Exception e) { throw new RuntimeException(e); } @@ -95,7 +83,7 @@ public class JtaTransactionWrapper implements KeycloakTransaction { @Override public boolean getRollbackOnly() { try { - return tm.getStatus() == Status.STATUS_MARKED_ROLLBACK; + return ut.getStatus() == Status.STATUS_MARKED_ROLLBACK; } catch (Exception e) { throw new RuntimeException(e); } @@ -104,28 +92,15 @@ public class JtaTransactionWrapper implements KeycloakTransaction { @Override public boolean isActive() { try { - return tm.getStatus() == Status.STATUS_ACTIVE; + return ut.getStatus() == Status.STATUS_ACTIVE; } catch (Exception e) { throw new RuntimeException(e); } } - /* - - @Override - protected void finalize() throws Throwable { - if (ended != null) { - logger.error("TX didn't close at position", ended); - } - - } - */ protected void end() { - ended = null; - logger.debug("JtaTransactionWrapper end"); if (suspended != null) { try { - logger.debug("JtaTransactionWrapper resuming suspended"); tm.resume(suspended); } catch (Exception e) { throw new RuntimeException(e); diff --git a/server-spi/src/main/java/org/keycloak/transaction/TransactionManagerLookupSpi.java b/services/src/main/java/org/keycloak/transaction/TransactionManagerLookupSpi.java similarity index 100% rename from server-spi/src/main/java/org/keycloak/transaction/TransactionManagerLookupSpi.java rename to services/src/main/java/org/keycloak/transaction/TransactionManagerLookupSpi.java diff --git a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi index 55b31a09f9..77cba5e1ef 100755 --- a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi +++ b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi @@ -18,4 +18,5 @@ org.keycloak.exportimport.ClientDescriptionConverterSpi org.keycloak.wellknown.WellKnownSpi org.keycloak.services.clientregistration.ClientRegistrationSpi +org.keycloak.transaction.TransactionManagerLookupSpi diff --git a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml index c823e4f3a3..326fa7f26f 100755 --- a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml +++ b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml @@ -29,7 +29,7 @@ sa - + h2