package org.keycloak.models.jpa;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.entities.*;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ApplicationAdapter implements ApplicationModel {
protected EntityManager em;
protected ApplicationEntity application;
public ApplicationAdapter(EntityManager em, ApplicationEntity application) {
this.em = em;
this.application = application;
}
@Override
public void updateApplication() {
em.flush();
}
@Override
public UserModel getApplicationUser() {
return new UserAdapter(application.getApplicationUser());
}
@Override
public String getId() {
return application.getId();
}
@Override
public String getName() {
return application.getName();
}
@Override
public void setName(String name) {
application.setName(name);
}
@Override
public boolean isEnabled() {
return application.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
application.setEnabled(enabled);
}
@Override
public boolean isSurrogateAuthRequired() {
return application.isSurrogateAuthRequired();
}
@Override
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
application.setSurrogateAuthRequired(surrogateAuthRequired);
}
@Override
public String getManagementUrl() {
return application.getManagementUrl();
}
@Override
public void setManagementUrl(String url) {
application.setManagementUrl(url);
}
@Override
public RoleModel getRole(String name) {
Collection<RoleEntity> roles = application.getRoles();
if (roles == null) return null;
for (RoleEntity role : roles) {
if (role.getName().equals(name)) {
return new RoleAdapter(role);
}
}
return null;
}
@Override
public RoleModel addRole(String name) {
RoleModel role = getRole(name);
if (role != null) return role;
RoleEntity entity = new RoleEntity();
entity.setName(name);
em.persist(entity);
application.getRoles().add(entity);
em.flush();
return new RoleAdapter(entity);
}
@Override
public boolean removeRole(String id) {
RoleEntity role = em.find(RoleEntity.class, id);
if (role == null) {
return false;
}
application.getRoles().remove(role);
application.getDefaultRoles().remove(role);
em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
em.createQuery("delete from " + RealmScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
em.createQuery("delete from " + RealmUserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
em.remove(role);
return true;
}
@Override
public List<RoleModel> getRoles() {
ArrayList<RoleModel> list = new ArrayList<RoleModel>();
Collection<RoleEntity> roles = application.getRoles();
if (roles == null) return list;
for (RoleEntity entity : roles) {
list.add(new RoleAdapter(entity));
}
return list;
}
@Override
public RoleModel getRoleById(String id) {
RoleEntity entity = em.find(RoleEntity.class, id);
if (entity == null) return null;
return new RoleAdapter(entity);
}
@Override
public boolean hasRole(UserModel user, RoleModel role) {
TypedQuery<ApplicationUserRoleMappingEntity> query = getApplicationUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
return query.getResultList().size() > 0;
}
protected TypedQuery<ApplicationUserRoleMappingEntity> getApplicationUserRoleMappingEntityTypedQuery(UserAdapter user, RoleAdapter role) {
TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userHasApplicationRole", ApplicationUserRoleMappingEntity.class);
query.setParameter("user", ((UserAdapter)user).getUser());
query.setParameter("role", ((RoleAdapter)role).getRole());
query.setParameter("application", application);
return query;
}
@Override
public void grantRole(UserModel user, RoleModel role) {
if (hasRole(user, role)) return;
ApplicationUserRoleMappingEntity entity = new ApplicationUserRoleMappingEntity();
entity.setApplication(application);
entity.setUser(((UserAdapter) user).getUser());
entity.setRole(((RoleAdapter)role).getRole());
em.persist(entity);
em.flush();
}
@Override
public List<RoleModel> getRoleMappings(UserModel user) {
TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userApplicationMappings", ApplicationUserRoleMappingEntity.class);
query.setParameter("user", ((UserAdapter)user).getUser());
query.setParameter("application", application);
List<ApplicationUserRoleMappingEntity> entities = query.getResultList();
List<RoleModel> roles = new ArrayList<RoleModel>();
for (ApplicationUserRoleMappingEntity entity : entities) {
roles.add(new RoleAdapter(entity.getRole()));
}
return roles;
}
@Override
public Set<String> getRoleMappingValues(UserModel user) {
TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userApplicationMappings", ApplicationUserRoleMappingEntity.class);
query.setParameter("user", ((UserAdapter)user).getUser());
query.setParameter("application", application);
List<ApplicationUserRoleMappingEntity> entities = query.getResultList();
Set<String> roles = new HashSet<String>();
for (ApplicationUserRoleMappingEntity entity : entities) {
roles.add(entity.getRole().getName());
}
return roles;
}
@Override
public void deleteRoleMapping(UserModel user, RoleModel role) {
TypedQuery<ApplicationUserRoleMappingEntity> query = getApplicationUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
List<ApplicationUserRoleMappingEntity> results = query.getResultList();
if (results.size() == 0) return;
for (ApplicationUserRoleMappingEntity entity : results) {
em.remove(entity);
}
}
@Override
public boolean hasRole(UserModel user, String roleName) {
RoleModel role = getRole(roleName);
if (role == null) return false;
return hasRole(user, role);
}
@Override
public void addScopeMapping(UserModel agent, String roleName) {
RoleModel role = getRole(roleName);
if (role == null) throw new RuntimeException("role does not exist");
addScopeMapping(agent, role);
}
@Override
public Set<String> getScopeMappingValues(UserModel agent) {
TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userApplicationScopeMappings", ApplicationScopeMappingEntity.class);
query.setParameter("user", ((UserAdapter)agent).getUser());
query.setParameter("application", application);
List<ApplicationScopeMappingEntity> entities = query.getResultList();
Set<String> roles = new HashSet<String>();
for (ApplicationScopeMappingEntity entity : entities) {
roles.add(entity.getRole().getName());
}
return roles;
}
@Override
public List<RoleModel> getScopeMappings(UserModel agent) {
TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userApplicationScopeMappings", ApplicationScopeMappingEntity.class);
query.setParameter("user", ((UserAdapter)agent).getUser());
query.setParameter("application", application);
List<ApplicationScopeMappingEntity> entities = query.getResultList();
List<RoleModel> roles = new ArrayList<RoleModel>();
for (ApplicationScopeMappingEntity entity : entities) {
roles.add(new RoleAdapter(entity.getRole()));
}
return roles;
}
@Override
public void addScopeMapping(UserModel agent, RoleModel role) {
if (hasScope(agent, role)) return;
ApplicationScopeMappingEntity entity = new ApplicationScopeMappingEntity();
entity.setApplication(application);
entity.setUser(((UserAdapter) agent).getUser());
entity.setRole(((RoleAdapter)role).getRole());
em.persist(entity);
em.flush();
}
@Override
public void deleteScopeMapping(UserModel user, RoleModel role) {
TypedQuery<ApplicationScopeMappingEntity> query = getApplicationScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
List<ApplicationScopeMappingEntity> results = query.getResultList();
if (results.size() == 0) return;
for (ApplicationScopeMappingEntity entity : results) {
em.remove(entity);
}
}
public boolean hasScope(UserModel user, RoleModel role) {
TypedQuery<ApplicationScopeMappingEntity> query = getApplicationScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
return query.getResultList().size() > 0;
}
protected TypedQuery<ApplicationScopeMappingEntity> getApplicationScopeMappingQuery(UserAdapter user, RoleAdapter role) {
TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userHasApplicationScope", ApplicationScopeMappingEntity.class);
query.setParameter("user", ((UserAdapter)user).getUser());
query.setParameter("role", ((RoleAdapter)role).getRole());
query.setParameter("application", application);
return query;
}
@Override
public List<String> getDefaultRoles() {
Collection<RoleEntity> entities = application.getDefaultRoles();
List<String> roles = new ArrayList<String>();
if (entities == null) return roles;
for (RoleEntity entity : entities) {
roles.add(entity.getName());
}
return roles;
}
@Override
public void addDefaultRole(String name) {
RoleModel role = getRole(name);
if (role == null) {
role = addRole(name);
}
Collection<RoleEntity> entities = application.getDefaultRoles();
for (RoleEntity entity : entities) {
if (entity.getId().equals(role.getId())) {
return;
}
}
entities.add(((RoleAdapter) role).getRole());
em.flush();
}
public static boolean contains(String str, String[] array) {
for (String s : array) {
if (str.equals(s)) return true;
}
return false;
}
@Override
public void updateDefaultRoles(String[] defaultRoles) {
Collection<RoleEntity> entities = application.getDefaultRoles();
Set<String> already = new HashSet<String>();
List<RoleEntity> remove = new ArrayList<RoleEntity>();
for (RoleEntity rel : entities) {
if (!contains(rel.getName(), defaultRoles)) {
remove.add(rel);
} else {
already.add(rel.getName());
}
}
for (RoleEntity entity : remove) {
entities.remove(entity);
}
em.flush();
for (String roleName : defaultRoles) {
if (!already.contains(roleName)) {
addDefaultRole(roleName);
}
}
em.flush();
}
}