From a5b0a8b6cadff1b48e3419204058b41fa349cece Mon Sep 17 00:00:00 2001 From: razvantufisi Date: Tue, 7 Jan 2025 14:41:30 +0200 Subject: [PATCH] #287 Optimization --- .../service/model/OrganizationModel.java | 3 +- .../model/jpa/OrganizationAdapter.java | 57 ++++---- .../model/jpa/OrganizationMemberAdapter.java | 42 +++--- .../OrganizationMemberAttributeEntity.java | 130 +++++++++--------- .../jpa/entity/OrganizationMemberEntity.java | 1 - .../UserOrganizationMember.java | 45 +++--- .../UserOrganizationMemberConverter.java | 98 ++++++------- .../AbstractCypressOrganizationTest.java | 4 +- .../service/AbstractOrganizationTest.java | 4 +- .../OrganizationIdpExportTest.java | 84 ++++++----- .../OrganizationSharedIdpExportTest.java | 93 +++++++------ 11 files changed, 286 insertions(+), 275 deletions(-) diff --git a/src/main/java/io/phasetwo/service/model/OrganizationModel.java b/src/main/java/io/phasetwo/service/model/OrganizationModel.java index 3d67b70..bc7eba5 100644 --- a/src/main/java/io/phasetwo/service/model/OrganizationModel.java +++ b/src/main/java/io/phasetwo/service/model/OrganizationModel.java @@ -43,7 +43,8 @@ public interface OrganizationModel extends WithAttributes { Stream getOrganizationMembersStream(); - Stream searchForOrganizationMembersStream(String search, Integer firstResult, Integer maxResults); + Stream searchForOrganizationMembersStream( + String search, Integer firstResult, Integer maxResults); boolean hasMembership(UserModel user); diff --git a/src/main/java/io/phasetwo/service/model/jpa/OrganizationAdapter.java b/src/main/java/io/phasetwo/service/model/jpa/OrganizationAdapter.java index b23095c..01f6d37 100644 --- a/src/main/java/io/phasetwo/service/model/jpa/OrganizationAdapter.java +++ b/src/main/java/io/phasetwo/service/model/jpa/OrganizationAdapter.java @@ -24,7 +24,12 @@ import io.phasetwo.service.util.IdentityProviders; import jakarta.persistence.EntityManager; import jakarta.persistence.TypedQuery; - +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.From; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; +import jakarta.persistence.criteria.Subquery; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -32,13 +37,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; - -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.From; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; -import jakarta.persistence.criteria.Subquery; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; @@ -210,17 +208,23 @@ public Stream searchForMembersStream( @Override public Stream getOrganizationMembersStream() { - TypedQuery query = em.createNamedQuery("getOrganizationMembers", OrganizationMemberEntity.class); + TypedQuery query = + em.createNamedQuery("getOrganizationMembers", OrganizationMemberEntity.class); query.setParameter("organization", org); - return query.getResultStream() - .map(organizationMemberEntity -> new OrganizationMemberAdapter(session, realm, em, organizationMemberEntity)); + return query + .getResultStream() + .map( + organizationMemberEntity -> + new OrganizationMemberAdapter(session, realm, em, organizationMemberEntity)); } @Override - public Stream searchForOrganizationMembersStream(String search, Integer firstResult, Integer maxResults) { + public Stream searchForOrganizationMembersStream( + String search, Integer firstResult, Integer maxResults) { CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); - CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(OrganizationMemberEntity.class); + CriteriaQuery criteriaQuery = + criteriaBuilder.createQuery(OrganizationMemberEntity.class); Root root = criteriaQuery.from(OrganizationMemberEntity.class); @@ -228,17 +232,21 @@ public Stream searchForOrganizationMembersStream(String // defining the organization search clause predicates.add(criteriaBuilder.equal(root.get("organization"), org)); if (search != null && !search.isEmpty()) { - var userIds = userIdsSubquery(criteriaQuery, search); + var userIds = userIdsSubquery(criteriaQuery, search); predicates.add(root.get("userId").in(userIds)); } - criteriaQuery.where(predicates.toArray(Predicate[]::new)).orderBy(criteriaBuilder.asc(root.get("createdAt"))); + criteriaQuery + .where(predicates.toArray(Predicate[]::new)) + .orderBy(criteriaBuilder.asc(root.get("createdAt"))); TypedQuery query = em.createQuery(criteriaQuery); return closing(paginateQuery(query, firstResult, maxResults).getResultStream()) - .filter(Objects::nonNull) - .map(organizationMemberEntity -> new OrganizationMemberAdapter(session, realm, em, organizationMemberEntity)); + .filter(Objects::nonNull) + .map( + organizationMemberEntity -> + new OrganizationMemberAdapter(session, realm, em, organizationMemberEntity)); } private Subquery userIdsSubquery(CriteriaQuery query, String search) { @@ -252,9 +260,9 @@ private Subquery userIdsSubquery(CriteriaQuery query, String search) subqueryPredicates.add(cb.equal(subRoot.get("realmId"), realm.getId())); List searchTermsPredicates = new ArrayList<>(); - //define search terms + // define search terms for (String stringToSearch : search.trim().split(",")) { - searchTermsPredicates.add(cb.or(getSearchOptionPredicateArray(stringToSearch, cb, subRoot))); + searchTermsPredicates.add(cb.or(getSearchOptionPredicateArray(stringToSearch, cb, subRoot))); } Predicate searchPredicate = cb.or(searchTermsPredicates.toArray(Predicate[]::new)); subqueryPredicates.add(searchPredicate); @@ -379,7 +387,8 @@ public Stream getRolesByUserStream(UserModel user) { @Override public OrganizationMemberModel getMembershipDetails(UserModel user) { - TypedQuery query = em.createNamedQuery("getOrganizationMemberByUserId", OrganizationMemberModel.class); + TypedQuery query = + em.createNamedQuery("getOrganizationMemberByUserId", OrganizationMemberModel.class); query.setParameter("organization", org); query.setParameter("id", user.getId()); return query.getSingleResult(); @@ -403,7 +412,8 @@ public OrganizationRoleModel addRole(String name) { @Override public Stream getIdentityProvidersStream() { - return session.identityProviders() + return session + .identityProviders() .getAllStream() // Todo: do we need to apply here a role filter? I believe not since its part of the // HomeIdpDiscoverer @@ -415,11 +425,12 @@ public Stream getIdentityProvidersStream() { }); } - private Predicate[] getSearchOptionPredicateArray(String value, CriteriaBuilder builder, From from) { + private Predicate[] getSearchOptionPredicateArray( + String value, CriteriaBuilder builder, From from) { value = value.trim().toLowerCase(); List orPredicates = new ArrayList<>(); if (!value.isEmpty()) { - value = "%" + value + "%"; //contains in SQL query manner + value = "%" + value + "%"; // contains in SQL query manner orPredicates.add(builder.like(from.get(USERNAME), value, ESCAPE_BACKSLASH)); orPredicates.add(builder.like(from.get(EMAIL), value, ESCAPE_BACKSLASH)); orPredicates.add(builder.like(builder.lower(from.get(FIRST_NAME)), value, ESCAPE_BACKSLASH)); diff --git a/src/main/java/io/phasetwo/service/model/jpa/OrganizationMemberAdapter.java b/src/main/java/io/phasetwo/service/model/jpa/OrganizationMemberAdapter.java index c76430d..1a72c54 100644 --- a/src/main/java/io/phasetwo/service/model/jpa/OrganizationMemberAdapter.java +++ b/src/main/java/io/phasetwo/service/model/jpa/OrganizationMemberAdapter.java @@ -2,22 +2,21 @@ import io.phasetwo.service.model.OrganizationMemberModel; import io.phasetwo.service.model.OrganizationModel; -import io.phasetwo.service.model.OrganizationProvider; -import io.phasetwo.service.model.jpa.entity.OrganizationMemberEntity; import io.phasetwo.service.model.jpa.entity.OrganizationMemberAttributeEntity; +import io.phasetwo.service.model.jpa.entity.OrganizationMemberEntity; import io.phasetwo.service.model.jpa.entity.OrganizationRoleEntity; import io.phasetwo.service.model.jpa.entity.UserOrganizationRoleMappingEntity; import jakarta.persistence.EntityManager; +import java.util.List; +import java.util.Map; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.jpa.JpaModel; import org.keycloak.models.utils.KeycloakModelUtils; -import java.util.List; -import java.util.Map; - -public class OrganizationMemberAdapter implements OrganizationMemberModel, JpaModel { +public class OrganizationMemberAdapter + implements OrganizationMemberModel, JpaModel { protected final KeycloakSession session; protected final OrganizationMemberEntity organizationMemberEntity; @@ -25,7 +24,10 @@ public class OrganizationMemberAdapter implements OrganizationMemberModel, JpaMo protected final RealmModel realm; public OrganizationMemberAdapter( - KeycloakSession session, RealmModel realm, EntityManager em, OrganizationMemberEntity organizationMemberEntity) { + KeycloakSession session, + RealmModel realm, + EntityManager em, + OrganizationMemberEntity organizationMemberEntity) { this.session = session; this.em = em; this.organizationMemberEntity = organizationMemberEntity; @@ -49,21 +51,21 @@ public String getUserId() { @Override public OrganizationModel getOrganization() { - return session - .getProvider(OrganizationProvider.class) - .getOrganizationById(realm, organizationMemberEntity.getOrganization().getId()); + return new OrganizationAdapter(session, realm, em, organizationMemberEntity.getOrganization()); } @Override public List getRoles() { - return organizationMemberEntity.getOrganization().getRoles() - .stream() - .flatMap(organizationRoleEntity -> organizationRoleEntity.getUserMappings().stream()) - .filter(userOrganizationRoleMappingEntity -> - userOrganizationRoleMappingEntity.getUserId().equals(organizationMemberEntity.getUserId())) - .map(UserOrganizationRoleMappingEntity::getRole) - .map(OrganizationRoleEntity::getName) - .toList(); + return organizationMemberEntity.getOrganization().getRoles().stream() + .flatMap(organizationRoleEntity -> organizationRoleEntity.getUserMappings().stream()) + .filter( + userOrganizationRoleMappingEntity -> + userOrganizationRoleMappingEntity + .getUserId() + .equals(organizationMemberEntity.getUserId())) + .map(UserOrganizationRoleMappingEntity::getRole) + .map(OrganizationRoleEntity::getName) + .toList(); } @Override @@ -77,7 +79,9 @@ public Map> getAttributes() { @Override public void removeAttribute(String name) { - organizationMemberEntity.getAttributes().removeIf(attribute -> attribute.getName().equals(name)); + organizationMemberEntity + .getAttributes() + .removeIf(attribute -> attribute.getName().equals(name)); } @Override diff --git a/src/main/java/io/phasetwo/service/model/jpa/entity/OrganizationMemberAttributeEntity.java b/src/main/java/io/phasetwo/service/model/jpa/entity/OrganizationMemberAttributeEntity.java index 9f653a1..e4d8ff5 100644 --- a/src/main/java/io/phasetwo/service/model/jpa/entity/OrganizationMemberAttributeEntity.java +++ b/src/main/java/io/phasetwo/service/model/jpa/entity/OrganizationMemberAttributeEntity.java @@ -10,75 +10,75 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; -import org.hibernate.annotations.Nationalized; - import java.util.Objects; +import org.hibernate.annotations.Nationalized; @Table( - name = "ORGANIZATION_MEMBER_ATTRIBUTE", - uniqueConstraints = {@UniqueConstraint(columnNames = {"ORGANIZATION_MEMBER_ID", "NAME"})}) + name = "ORGANIZATION_MEMBER_ATTRIBUTE", + uniqueConstraints = {@UniqueConstraint(columnNames = {"ORGANIZATION_MEMBER_ID", "NAME"})}) @Entity public class OrganizationMemberAttributeEntity { - @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 = "ORGANIZATION_MEMBER_ID") - protected OrganizationMemberEntity organizationMember; - - @Column(name = "NAME") - protected String name; - - @Nationalized - @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 OrganizationMemberEntity getOrganizationMember() { - return organizationMember; - } - - public void setOrganizationMember(OrganizationMemberEntity organizationMember) { - this.organizationMember = organizationMember; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (o == null || getClass() != o.getClass()) return false; - OrganizationMemberAttributeEntity that = (OrganizationMemberAttributeEntity) o; - return Objects.equals(id, that.id) && Objects.equals(organizationMember, that.organizationMember); - } - - @Override - public int hashCode() { - return Objects.hash(id, organizationMember); - } + @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 = "ORGANIZATION_MEMBER_ID") + protected OrganizationMemberEntity organizationMember; + + @Column(name = "NAME") + protected String name; + + @Nationalized + @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 OrganizationMemberEntity getOrganizationMember() { + return organizationMember; + } + + public void setOrganizationMember(OrganizationMemberEntity organizationMember) { + this.organizationMember = organizationMember; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + OrganizationMemberAttributeEntity that = (OrganizationMemberAttributeEntity) o; + return Objects.equals(id, that.id) + && Objects.equals(organizationMember, that.organizationMember); + } + + @Override + public int hashCode() { + return Objects.hash(id, organizationMember); + } } diff --git a/src/main/java/io/phasetwo/service/model/jpa/entity/OrganizationMemberEntity.java b/src/main/java/io/phasetwo/service/model/jpa/entity/OrganizationMemberEntity.java index 827cdfc..3e4e59e 100644 --- a/src/main/java/io/phasetwo/service/model/jpa/entity/OrganizationMemberEntity.java +++ b/src/main/java/io/phasetwo/service/model/jpa/entity/OrganizationMemberEntity.java @@ -17,7 +17,6 @@ import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; import jakarta.persistence.UniqueConstraint; - import java.util.ArrayList; import java.util.Collection; import java.util.Date; diff --git a/src/main/java/io/phasetwo/service/representation/UserOrganizationMember.java b/src/main/java/io/phasetwo/service/representation/UserOrganizationMember.java index b50033d..b34674c 100644 --- a/src/main/java/io/phasetwo/service/representation/UserOrganizationMember.java +++ b/src/main/java/io/phasetwo/service/representation/UserOrganizationMember.java @@ -1,37 +1,36 @@ package io.phasetwo.service.representation; -import org.keycloak.representations.idm.UserRepresentation; - import java.util.List; import java.util.Map; +import org.keycloak.representations.idm.UserRepresentation; public class UserOrganizationMember extends UserRepresentation { - Map> organizationAttributes; - String organizationId; - List organizationRoles; + Map> organizationMemberAttributes; + String organizationId; + List organizationRoles; - public Map> getOrganizationAttributes() { - return organizationAttributes; - } + public Map> getOrganizationMemberAttributes() { + return organizationMemberAttributes; + } - public void setOrganizationAttributes(Map> organizationAttributes) { - this.organizationAttributes = organizationAttributes; - } + public void setOrganizationMemberAttributes(Map> organizationMemberAttributes) { + this.organizationMemberAttributes = organizationMemberAttributes; + } - public String getOrganizationId() { - return organizationId; - } + public String getOrganizationId() { + return organizationId; + } - public void setOrganizationId(String organizationId) { - this.organizationId = organizationId; - } + public void setOrganizationId(String organizationId) { + this.organizationId = organizationId; + } - public List getOrganizationRoles() { - return organizationRoles; - } + public List getOrganizationRoles() { + return organizationRoles; + } - public void setOrganizationRoles(List organizationRoles) { - this.organizationRoles = organizationRoles; - } + public void setOrganizationRoles(List organizationRoles) { + this.organizationRoles = organizationRoles; + } } diff --git a/src/main/java/io/phasetwo/service/resource/UserOrganizationMemberConverter.java b/src/main/java/io/phasetwo/service/resource/UserOrganizationMemberConverter.java index fb5730a..14e6b19 100644 --- a/src/main/java/io/phasetwo/service/resource/UserOrganizationMemberConverter.java +++ b/src/main/java/io/phasetwo/service/resource/UserOrganizationMemberConverter.java @@ -1,62 +1,62 @@ package io.phasetwo.service.resource; +import static org.keycloak.models.light.LightweightUserAdapter.isLightweightUser; + import io.phasetwo.service.model.OrganizationMemberModel; import io.phasetwo.service.representation.UserOrganizationMember; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.credential.OTPCredentialModel; - import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; - -import static org.keycloak.models.light.LightweightUserAdapter.isLightweightUser; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.credential.OTPCredentialModel; public final class UserOrganizationMemberConverter { - public static UserOrganizationMember toRepresentation(KeycloakSession session, - RealmModel realm, - OrganizationMemberModel organizationMemberModel - ) { - var rep = new UserOrganizationMember(); - - var user = session.users().getUserById(realm, organizationMemberModel.getUserId()); - rep.setId(user.getId()); - rep.setUsername(user.getUsername()); - rep.setCreatedTimestamp(user.getCreatedTimestamp()); - rep.setLastName(user.getLastName()); - rep.setFirstName(user.getFirstName()); - rep.setEmail(user.getEmail()); - rep.setEnabled(user.isEnabled()); - rep.setEmailVerified(user.isEmailVerified()); - rep.setTotp(user.credentialManager().isConfiguredFor(OTPCredentialModel.TYPE)); - rep.setDisableableCredentialTypes(user.credentialManager() - .getDisableableCredentialTypesStream().collect(Collectors.toSet())); - rep.setFederationLink(user.getFederationLink()); - rep.setNotBefore(isLightweightUser(user) ? user.getCreatedTimestamp().intValue() : session.users().getNotBeforeOfUser(realm, user)); - rep.setRequiredActions(user.getRequiredActionsStream().collect(Collectors.toList())); - - Map> attributes = user.getAttributes(); - Map> copy = null; - - if (attributes != null) { - copy = new HashMap<>(attributes); - copy.remove(UserModel.LAST_NAME); - copy.remove(UserModel.FIRST_NAME); - copy.remove(UserModel.EMAIL); - copy.remove(UserModel.USERNAME); - } - if (attributes != null && !copy.isEmpty()) { - Map> attrs = new HashMap<>(copy); - rep.setAttributes(attrs); - } - - rep.setOrganizationAttributes(organizationMemberModel.getAttributes()); - rep.setOrganizationId(organizationMemberModel.getOrganization().getId()); - rep.setOrganizationRoles(organizationMemberModel.getRoles()); - - return rep; + public static UserOrganizationMember toRepresentation( + KeycloakSession session, RealmModel realm, OrganizationMemberModel organizationMemberModel) { + var rep = new UserOrganizationMember(); + + var user = session.users().getUserById(realm, organizationMemberModel.getUserId()); + rep.setId(user.getId()); + rep.setUsername(user.getUsername()); + rep.setCreatedTimestamp(user.getCreatedTimestamp()); + rep.setLastName(user.getLastName()); + rep.setFirstName(user.getFirstName()); + rep.setEmail(user.getEmail()); + rep.setEnabled(user.isEnabled()); + rep.setEmailVerified(user.isEmailVerified()); + rep.setTotp(user.credentialManager().isConfiguredFor(OTPCredentialModel.TYPE)); + rep.setDisableableCredentialTypes( + user.credentialManager().getDisableableCredentialTypesStream().collect(Collectors.toSet())); + rep.setFederationLink(user.getFederationLink()); + rep.setNotBefore( + isLightweightUser(user) + ? user.getCreatedTimestamp().intValue() + : session.users().getNotBeforeOfUser(realm, user)); + rep.setRequiredActions(user.getRequiredActionsStream().collect(Collectors.toList())); + + Map> attributes = user.getAttributes(); + Map> copy = null; + + if (attributes != null) { + copy = new HashMap<>(attributes); + copy.remove(UserModel.LAST_NAME); + copy.remove(UserModel.FIRST_NAME); + copy.remove(UserModel.EMAIL); + copy.remove(UserModel.USERNAME); + } + if (attributes != null && !copy.isEmpty()) { + Map> attrs = new HashMap<>(copy); + rep.setAttributes(attrs); } + + rep.setOrganizationMemberAttributes(organizationMemberModel.getAttributes()); + rep.setOrganizationId(organizationMemberModel.getOrganization().getId()); + rep.setOrganizationRoles(organizationMemberModel.getRoles()); + + return rep; + } } diff --git a/src/test/java/io/phasetwo/service/AbstractCypressOrganizationTest.java b/src/test/java/io/phasetwo/service/AbstractCypressOrganizationTest.java index bf261b3..a4eee84 100644 --- a/src/test/java/io/phasetwo/service/AbstractCypressOrganizationTest.java +++ b/src/test/java/io/phasetwo/service/AbstractCypressOrganizationTest.java @@ -41,8 +41,8 @@ public class AbstractCypressOrganizationTest { Boolean.parseBoolean(System.getProperty("include.cypress", "false")); public static final String KEYCLOAK_IMAGE = - String.format( - "quay.io/phasetwo/keycloak-crdb:%s", System.getProperty("keycloak-version", "26.0.2")); + String.format( + "quay.io/phasetwo/keycloak-crdb:%s", System.getProperty("keycloak-version", "26.0.2")); public static final String REALM = "master"; public static final String ADMIN_CLI = "admin-cli"; diff --git a/src/test/java/io/phasetwo/service/AbstractOrganizationTest.java b/src/test/java/io/phasetwo/service/AbstractOrganizationTest.java index 373bbbe..cac5337 100644 --- a/src/test/java/io/phasetwo/service/AbstractOrganizationTest.java +++ b/src/test/java/io/phasetwo/service/AbstractOrganizationTest.java @@ -54,7 +54,7 @@ public abstract class AbstractOrganizationTest { public static final String KEYCLOAK_IMAGE = - String.format( + String.format( "quay.io/phasetwo/keycloak-crdb:%s", System.getProperty("keycloak-version", "26.0.2")); public static final String REALM = "master"; public static final String ADMIN_CLI = "admin-cli"; @@ -928,6 +928,6 @@ protected ClientRepresentation createPublicClientInRealm(RealmResource realm, St client.setFullScopeAllowed(false); realm.clients().create(client).close(); - return realm.clients().findByClientId(client.getClientId()).getFirst(); + return realm.clients().findByClientId(client.getClientId()).getFirst(); } } diff --git a/src/test/java/io/phasetwo/service/importexport/OrganizationIdpExportTest.java b/src/test/java/io/phasetwo/service/importexport/OrganizationIdpExportTest.java index 40a8fb1..f8d03ed 100644 --- a/src/test/java/io/phasetwo/service/importexport/OrganizationIdpExportTest.java +++ b/src/test/java/io/phasetwo/service/importexport/OrganizationIdpExportTest.java @@ -3,17 +3,15 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertTrue; import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.collect.ImmutableMap; import io.phasetwo.client.openapi.model.OrganizationRepresentation; import io.phasetwo.service.AbstractOrganizationTest; import io.phasetwo.service.representation.LinkIdp; +import io.phasetwo.service.representation.OrganizationsConfig; import java.io.IOException; import java.util.List; - -import io.phasetwo.service.representation.OrganizationsConfig; import lombok.extern.jbosslog.JBossLog; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -85,43 +83,43 @@ void testOrganizationLinkIdp() throws IOException { void testOrganizationChangeLink() throws IOException { // create organization var organization1 = - createOrganization( - new OrganizationRepresentation() - .name("example-org") - .domains(List.of("example.com", "test.org"))); + createOrganization( + new OrganizationRepresentation() + .name("example-org") + .domains(List.of("example.com", "test.org"))); // create organization var organization2 = - createOrganization( - new OrganizationRepresentation() - .name("example-org2") - .domains(List.of("example2.com", "test2.org"))); + createOrganization( + new OrganizationRepresentation() + .name("example-org2") + .domains(List.of("example2.com", "test2.org"))); // create identity provider String alias1 = "linking-provider-1"; org.keycloak.representations.idm.IdentityProviderRepresentation idp = - new org.keycloak.representations.idm.IdentityProviderRepresentation(); + new org.keycloak.representations.idm.IdentityProviderRepresentation(); idp.setAlias(alias1); idp.setProviderId("oidc"); idp.setEnabled(true); idp.setFirstBrokerLoginFlowAlias("first broker login"); idp.setConfig( - new ImmutableMap.Builder() - .put("useJwksUrl", "true") - .put("syncMode", "FORCE") - .put("authorizationUrl", "https://foo.com") - .put("hideOnLoginPage", "") - .put("loginHint", "") - .put("uiLocales", "") - .put("backchannelSupported", "") - .put("disableUserInfo", "") - .put("acceptsPromptNoneForwardFromClient", "") - .put("validateSignature", "") - .put("pkceEnabled", "") - .put("tokenUrl", "https://foo.com") - .put("clientAuthMethod", "client_secret_post") - .put("clientId", "aabbcc") - .put("clientSecret", "112233") - .build()); + new ImmutableMap.Builder() + .put("useJwksUrl", "true") + .put("syncMode", "FORCE") + .put("authorizationUrl", "https://foo.com") + .put("hideOnLoginPage", "") + .put("loginHint", "") + .put("uiLocales", "") + .put("backchannelSupported", "") + .put("disableUserInfo", "") + .put("acceptsPromptNoneForwardFromClient", "") + .put("validateSignature", "") + .put("pkceEnabled", "") + .put("tokenUrl", "https://foo.com") + .put("clientAuthMethod", "client_secret_post") + .put("clientId", "aabbcc") + .put("clientSecret", "112233") + .build()); keycloak.realm(REALM).identityProviders().create(idp); // link org1 @@ -130,8 +128,8 @@ void testOrganizationChangeLink() throws IOException { link1.setSyncMode("IMPORT"); var responseOrg1Link = postRequest(link1, organization1.getId(), "idps", "link"); assertThat( - responseOrg1Link.getStatusCode(), - is(jakarta.ws.rs.core.Response.Status.CREATED.getStatusCode())); + responseOrg1Link.getStatusCode(), + is(jakarta.ws.rs.core.Response.Status.CREATED.getStatusCode())); // link org2 var link2 = new LinkIdp(); @@ -139,8 +137,8 @@ void testOrganizationChangeLink() throws IOException { link2.setSyncMode("IMPORT"); var responseOrg2Link = postRequest(link2, organization2.getId(), "idps", "link"); assertThat( - responseOrg2Link.getStatusCode(), - is(jakarta.ws.rs.core.Response.Status.CREATED.getStatusCode())); + responseOrg2Link.getStatusCode(), + is(jakarta.ws.rs.core.Response.Status.CREATED.getStatusCode())); // export var export = exportOrgs(keycloak, true); @@ -148,15 +146,15 @@ void testOrganizationChangeLink() throws IOException { // validate org1 export.getOrganizations().stream() - .filter(exportOrg -> exportOrg.getOrganization().getName().equals(organization1.getName())) - .findFirst() - .ifPresent(exportOrg -> Assertions.assertNull(exportOrg.getIdpLink())); + .filter(exportOrg -> exportOrg.getOrganization().getName().equals(organization1.getName())) + .findFirst() + .ifPresent(exportOrg -> Assertions.assertNull(exportOrg.getIdpLink())); // validate org2 export.getOrganizations().stream() - .filter(exportOrg -> exportOrg.getOrganization().getName().equals(organization2.getName())) - .findFirst() - .ifPresent(exportOrg -> assertThat(exportOrg.getIdpLink(), is(alias1))); + .filter(exportOrg -> exportOrg.getOrganization().getName().equals(organization2.getName())) + .findFirst() + .ifPresent(exportOrg -> assertThat(exportOrg.getIdpLink(), is(alias1))); // delete org1 deleteOrganization(organization1.getId()); @@ -176,8 +174,8 @@ public void beforeEach() throws JsonProcessingException { orgConfig.setSharedIdps(false); var responseOrgsConfig = putRequest(orgConfig, url); assertThat( - responseOrgsConfig.getStatusCode(), - is(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())); + responseOrgsConfig.getStatusCode(), + is(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())); } @AfterEach @@ -188,7 +186,7 @@ public void afterEach() throws JsonProcessingException { orgConfig.setSharedIdps(false); var responseOrgsConfig = putRequest(orgConfig, url); assertThat( - responseOrgsConfig.getStatusCode(), - is(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())); + responseOrgsConfig.getStatusCode(), + is(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())); } } diff --git a/src/test/java/io/phasetwo/service/importexport/OrganizationSharedIdpExportTest.java b/src/test/java/io/phasetwo/service/importexport/OrganizationSharedIdpExportTest.java index db97c61..7251e2c 100644 --- a/src/test/java/io/phasetwo/service/importexport/OrganizationSharedIdpExportTest.java +++ b/src/test/java/io/phasetwo/service/importexport/OrganizationSharedIdpExportTest.java @@ -1,23 +1,22 @@ package io.phasetwo.service.importexport; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; + import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.collect.ImmutableMap; import io.phasetwo.client.openapi.model.OrganizationRepresentation; import io.phasetwo.service.AbstractOrganizationTest; import io.phasetwo.service.representation.LinkIdp; import io.phasetwo.service.representation.OrganizationsConfig; +import java.io.IOException; +import java.util.List; import lombok.extern.jbosslog.JBossLog; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; -import java.util.List; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; - @JBossLog public class OrganizationSharedIdpExportTest extends AbstractOrganizationTest { @@ -25,43 +24,43 @@ public class OrganizationSharedIdpExportTest extends AbstractOrganizationTest { void testMultiOrganizationLink() throws IOException { // create organization var organization1 = - createOrganization( - new OrganizationRepresentation() - .name("example-org") - .domains(List.of("example.com", "test.org"))); + createOrganization( + new OrganizationRepresentation() + .name("example-org") + .domains(List.of("example.com", "test.org"))); // create organization var organization2 = - createOrganization( - new OrganizationRepresentation() - .name("example-org2") - .domains(List.of("example2.com", "test2.org"))); + createOrganization( + new OrganizationRepresentation() + .name("example-org2") + .domains(List.of("example2.com", "test2.org"))); // create identity provider String alias1 = "linking-provider-1"; org.keycloak.representations.idm.IdentityProviderRepresentation idp = - new org.keycloak.representations.idm.IdentityProviderRepresentation(); + new org.keycloak.representations.idm.IdentityProviderRepresentation(); idp.setAlias(alias1); idp.setProviderId("oidc"); idp.setEnabled(true); idp.setFirstBrokerLoginFlowAlias("first broker login"); idp.setConfig( - new ImmutableMap.Builder() - .put("useJwksUrl", "true") - .put("syncMode", "FORCE") - .put("authorizationUrl", "https://foo.com") - .put("hideOnLoginPage", "") - .put("loginHint", "") - .put("uiLocales", "") - .put("backchannelSupported", "") - .put("disableUserInfo", "") - .put("acceptsPromptNoneForwardFromClient", "") - .put("validateSignature", "") - .put("pkceEnabled", "") - .put("tokenUrl", "https://foo.com") - .put("clientAuthMethod", "client_secret_post") - .put("clientId", "aabbcc") - .put("clientSecret", "112233") - .build()); + new ImmutableMap.Builder() + .put("useJwksUrl", "true") + .put("syncMode", "FORCE") + .put("authorizationUrl", "https://foo.com") + .put("hideOnLoginPage", "") + .put("loginHint", "") + .put("uiLocales", "") + .put("backchannelSupported", "") + .put("disableUserInfo", "") + .put("acceptsPromptNoneForwardFromClient", "") + .put("validateSignature", "") + .put("pkceEnabled", "") + .put("tokenUrl", "https://foo.com") + .put("clientAuthMethod", "client_secret_post") + .put("clientId", "aabbcc") + .put("clientSecret", "112233") + .build()); keycloak.realm(REALM).identityProviders().create(idp); // link org1 @@ -70,8 +69,8 @@ void testMultiOrganizationLink() throws IOException { link1.setSyncMode("IMPORT"); var responseOrg1Link = postRequest(link1, organization1.getId(), "idps", "link"); assertThat( - responseOrg1Link.getStatusCode(), - is(jakarta.ws.rs.core.Response.Status.CREATED.getStatusCode())); + responseOrg1Link.getStatusCode(), + is(jakarta.ws.rs.core.Response.Status.CREATED.getStatusCode())); // link org2 var link2 = new LinkIdp(); @@ -79,8 +78,8 @@ void testMultiOrganizationLink() throws IOException { link2.setSyncMode("IMPORT"); var responseOrg2Link = postRequest(link2, organization2.getId(), "idps", "link"); assertThat( - responseOrg2Link.getStatusCode(), - is(jakarta.ws.rs.core.Response.Status.CREATED.getStatusCode())); + responseOrg2Link.getStatusCode(), + is(jakarta.ws.rs.core.Response.Status.CREATED.getStatusCode())); // export var export = exportOrgs(keycloak, true); @@ -88,15 +87,15 @@ void testMultiOrganizationLink() throws IOException { // validate org1 export.getOrganizations().stream() - .filter(exportOrg -> exportOrg.getOrganization().getName().equals(organization1.getName())) - .findFirst() - .ifPresent(exportOrg -> assertThat(exportOrg.getIdpLink(), is(alias1))); + .filter(exportOrg -> exportOrg.getOrganization().getName().equals(organization1.getName())) + .findFirst() + .ifPresent(exportOrg -> assertThat(exportOrg.getIdpLink(), is(alias1))); // validate org2 export.getOrganizations().stream() - .filter(exportOrg -> exportOrg.getOrganization().getName().equals(organization2.getName())) - .findFirst() - .ifPresent(exportOrg -> assertThat(exportOrg.getIdpLink(), is(alias1))); + .filter(exportOrg -> exportOrg.getOrganization().getName().equals(organization2.getName())) + .findFirst() + .ifPresent(exportOrg -> assertThat(exportOrg.getIdpLink(), is(alias1))); // delete org1 deleteOrganization(organization1.getId()); @@ -116,8 +115,8 @@ public void beforeEach() throws JsonProcessingException { orgConfig.setSharedIdps(true); var responseOrgsConfig = putRequest(orgConfig, url); assertThat( - responseOrgsConfig.getStatusCode(), - is(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())); + responseOrgsConfig.getStatusCode(), + is(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())); } @AfterEach @@ -128,7 +127,7 @@ public void afterEach() throws JsonProcessingException { orgConfig.setSharedIdps(true); var responseOrgsConfig = putRequest(orgConfig, url); assertThat( - responseOrgsConfig.getStatusCode(), - is(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())); + responseOrgsConfig.getStatusCode(), + is(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())); } }