package org.keycloak.models.jpa;
import org.keycloak.migration.MigrationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientTemplateModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.ClientEntity;
import org.keycloak.models.jpa.entities.ClientTemplateEntity;
import org.keycloak.models.jpa.entities.GroupEntity;
import org.keycloak.models.jpa.entities.RealmEntity;
import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class JpaRealmProvider implements RealmProvider {
private final KeycloakSession session;
protected EntityManager em;
public JpaRealmProvider(KeycloakSession session, EntityManager em) {
this.session = session;
this.em = em;
}
@Override
public MigrationModel getMigrationModel() {
return new MigrationModelAdapter(em);
}
@Override
public RealmModel createRealm(String name) {
return createRealm(KeycloakModelUtils.generateId(), name);
}
@Override
public RealmModel createRealm(String id, String name) {
RealmEntity realm = new RealmEntity();
realm.setName(name);
realm.setId(id);
em.persist(realm);
em.flush();
final RealmModel model = new RealmAdapter(session, em, realm);
session.getKeycloakSessionFactory().publish(new RealmModel.RealmCreationEvent() {
@Override
public RealmModel getCreatedRealm() {
return model;
}
});
return model;
}
@Override
public RealmModel getRealm(String id) {
RealmEntity realm = em.find(RealmEntity.class, id);
if (realm == null) return null;
return new RealmAdapter(session, em, realm);
}
@Override
public List<RealmModel> getRealms() {
TypedQuery<RealmEntity> query = em.createNamedQuery("getAllRealms", RealmEntity.class);
List<RealmEntity> entities = query.getResultList();
List<RealmModel> realms = new ArrayList<RealmModel>();
for (RealmEntity entity : entities) {
realms.add(new RealmAdapter(session, em, entity));
}
return realms;
}
@Override
public RealmModel getRealmByName(String name) {
TypedQuery<RealmEntity> query = em.createNamedQuery("getRealmByName", RealmEntity.class);
query.setParameter("name", name);
List<RealmEntity> entities = query.getResultList();
if (entities.size() == 0) return null;
if (entities.size() > 1) throw new IllegalStateException("Should not be more than one realm with same name");
RealmEntity realm = query.getResultList().get(0);
if (realm == null) return null;
return new RealmAdapter(session, em, realm);
}
@Override
public boolean removeRealm(String id) {
RealmEntity realm = em.find(RealmEntity.class, id);
if (realm == null) {
return false;
}
RealmAdapter adapter = new RealmAdapter(session, em, realm);
session.users().preRemove(adapter);
int num = em.createNamedQuery("deleteGroupRoleMappingsByRealm")
.setParameter("realm", realm).executeUpdate();
num = em.createNamedQuery("deleteGroupAttributesByRealm")
.setParameter("realm", realm).executeUpdate();
num = em.createNamedQuery("deleteGroupsByRealm")
.setParameter("realm", realm).executeUpdate();
for (ClientEntity a : new LinkedList<>(realm.getClients())) {
adapter.removeClient(a.getId());
}
em.remove(realm);
em.flush();
em.clear();
return true;
}
@Override
public void close() {
}
@Override
public RoleModel getRoleById(String id, RealmModel realm) {
RoleEntity entity = em.find(RoleEntity.class, id);
if (entity == null) return null;
if (!realm.getId().equals(entity.getRealmId())) return null;
return new RoleAdapter(realm, em, entity);
}
@Override
public GroupModel getGroupById(String id, RealmModel realm) {
GroupEntity groupEntity = em.find(GroupEntity.class, id);
if (groupEntity == null) return null;
if (!groupEntity.getRealm().getId().equals(realm.getId())) return null;
return new GroupAdapter(realm, em, groupEntity);
}
@Override
public ClientModel getClientById(String id, RealmModel realm) {
ClientEntity app = em.find(ClientEntity.class, id);
// Check if application belongs to this realm
if (app == null || !realm.getId().equals(app.getRealm().getId())) return null;
return new ClientAdapter(realm, em, session, app);
}
@Override
public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
ClientTemplateEntity app = em.find(ClientTemplateEntity.class, id);
// Check if application belongs to this realm
if (app == null || !realm.getId().equals(app.getRealm().getId())) return null;
return new ClientTemplateAdapter(realm, em, session, app);
}
}