Skip to content

Commit

Permalink
SHIBUI-1783
Browse files Browse the repository at this point in the history
Backend updates to saving filter to include any custom entity attributes
  • Loading branch information
chasegawa committed May 28, 2021
1 parent 0d63979 commit 0cfbe25
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

import org.hibernate.envers.Audited;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.filters;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.hibernate.envers.Audited;

import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition;
import lombok.Getter;
import lombok.Setter;


@Entity(name = "custom_entity_attr_filter_value")
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "filter_id", "custom_entity_attribute_name" }) })
@Audited
// NOTE: lombok's toString and equals cause an infinite loop somewhere that causes stack overflows, so if we need impls,
// do it manually. Do not replace the Getter and Setter with @Data...
@Getter
@Setter
public class CustomEntityAttributeFilterValue {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "generated_id")
private Integer id;

@ManyToOne
@JoinColumn(name = "filter_id", nullable = false)
EntityAttributesFilter entityAttributesFilter;

@ManyToOne
@JoinColumn(name = "custom_entity_attribute_name", referencedColumnName = "name", nullable = false)
CustomEntityAttributeDefinition customEntityAttributeDefinition;

@Column(name = "value", nullable = false)
String value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@
import org.hibernate.envers.Audited;

import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderColumn;
import javax.persistence.PostLoad;
import javax.persistence.Transient;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions.getAttributeListFromAttributeReleaseList;
import static edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions.getAttributeListFromRelyingPartyOverridesRepresentation;
Expand All @@ -32,6 +37,7 @@
@ToString
@Audited
public class EntityAttributesFilter extends MetadataFilter {
private static final long serialVersionUID = 1L;

public EntityAttributesFilter() {
type = "EntityAttributes";
Expand All @@ -47,7 +53,16 @@ public EntityAttributesFilter() {

@Transient
private List<String> attributeRelease = new ArrayList<>();

@JsonIgnore
@OneToMany(cascade = CascadeType.ALL, mappedBy = "entityAttributesFilter", orphanRemoval = true)
private Set<CustomEntityAttributeFilterValue> customEntityAttributes = new HashSet<>();

public void setCustomEntityAttributes (Set<CustomEntityAttributeFilterValue> newValues) {
customEntityAttributes.clear();
customEntityAttributes.addAll(newValues);
}

public void setAttributeRelease(List<String> attributeRelease) {
this.attributeRelease = attributeRelease;
this.rebuildAttributes();
Expand Down Expand Up @@ -80,6 +95,7 @@ private EntityAttributesFilter updateConcreteFilterTypeData(EntityAttributesFilt
filterToBeUpdated.setEntityAttributesFilterTarget(getEntityAttributesFilterTarget());
filterToBeUpdated.setRelyingPartyOverrides(getRelyingPartyOverrides());
filterToBeUpdated.setAttributeRelease(getAttributeRelease());
filterToBeUpdated.setCustomEntityAttributes(customEntityAttributes);
return filterToBeUpdated;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package edu.internet2.tier.shibboleth.admin.ui.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.CustomEntityAttributeFilterValue;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter;

// Not entirely sure this is needed for the core, but it did make validation/unit testing a whole lot easier
public interface CustomEntityAttributeFilterValueRepository extends JpaRepository<CustomEntityAttributeFilterValue, Long> {
CustomEntityAttributeFilterValue findByEntityAttributesFilterAndCustomEntityAttributeDefinition(EntityAttributesFilter eaf , CustomEntityAttributeDefinition cead);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfigurat
import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration
import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration
import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration
import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.CustomEntityAttributeFilterValue
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter
import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -27,6 +29,12 @@ class FilterRepositoryTests extends Specification {
@Autowired
FilterRepository repositoryUnderTest

@Autowired
CustomEntityAttributeDefinitionRepository ceadRepo

@Autowired
CustomEntityAttributeFilterValueRepository ceafvRepo

@Autowired
EntityManager entityManager

Expand Down Expand Up @@ -85,4 +93,88 @@ class FilterRepositoryTests extends Specification {
persistedFilter.audId > 0L
persistedFilter.formats.size() == 1
}

def "FilterRepository + EntityAttributesFilter CRUD ops with custom entity attributes correctly"(){
given:
def ca = new CustomEntityAttributeDefinition().with {
it.name = "ca-name"
it.attributeType = "STRING"
it.defaultValue = "foo"
it
}
ceadRepo.save(ca)
entityManager.flush()
entityManager.clear()

def entityAttributesFilterJson = '''{
"name": "EntityAttributes",
"resourceId": "29a5d409-562a-41cd-acee-e9b3d7098d05",
"filterEnabled": false,
"entityAttributesFilterTarget": {
"entityAttributesFilterTargetType": "CONDITION_SCRIPT",
"value": [
"TwUuSOz5O6"
]
},
"attributeRelease": [
"WbkhLQNI3m"
],
"relyingPartyOverrides": {
"signAssertion": true,
"dontSignResponse": true,
"turnOffEncryption": true,
"useSha": true,
"ignoreAuthenticationMethod": false,
"omitNotBefore": true,
"responderId": null,
"nameIdFormats": [
"xLenUFmCLn"
],
"authenticationMethods": []
},
"@type": "EntityAttributes"
}'''
def filter = new ObjectMapper().readValue(entityAttributesFilterJson.bytes, EntityAttributesFilter.class)
def persistedFilter = repositoryUnderTest.save(filter)
entityManager.flush()

def savedFilter = repositoryUnderTest.findByResourceId(persistedFilter.resourceId)
def saveEAD = ceadRepo.findByName("ca-name");

def ceafv = new CustomEntityAttributeFilterValue().with {
it.entityAttributesFilter = savedFilter
it.customEntityAttributeDefinition = saveEAD
it.value = "bar"
it
}

def customEntityAttributes = new HashSet()

when:
customEntityAttributes.add(ceafv) // nothing to do yet, just here to let us verify nothing in the CEAFV table in 'then' block

then:
((Set)ceafvRepo.findAll()).size() == 0 //nothing yet
((EntityAttributesFilter)savedFilter).setCustomEntityAttributes(customEntityAttributes)
repositoryUnderTest.save(savedFilter)
entityManager.flush()

then:
def listOfceafv = ceafvRepo.findAll()
listOfceafv.size() == 1

def ceafvFromDb = listOfceafv.get(0).asType(CustomEntityAttributeFilterValue)
ceafvFromDb.getEntityAttributesFilter().getResourceId().equals("29a5d409-562a-41cd-acee-e9b3d7098d05")

def filterFromDb = (EntityAttributesFilter) repositoryUnderTest.findByResourceId("29a5d409-562a-41cd-acee-e9b3d7098d05")
filterFromDb.getCustomEntityAttributes().size() == 1

// now remove all
def emptySet = new HashSet()
filterFromDb.setCustomEntityAttributes(emptySet)
repositoryUnderTest.save(filterFromDb)
entityManager.flush()

ceafvRepo.findAll().size() == 0
}
}

0 comments on commit 0cfbe25

Please sign in to comment.