Skip to content

Commit

Permalink
Merged in SHIBUI-1684 (pull request #453)
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed Dec 11, 2019
2 parents db969b8 + 6e6b9d8 commit 29bfc0e
Show file tree
Hide file tree
Showing 25 changed files with 732 additions and 26 deletions.
9 changes: 5 additions & 4 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ repositories {
configurations.all {
resolutionStrategy {
force 'org.cryptacular:cryptacular:1.1.3'

eachDependency { details ->
if (details.requested.group == 'org.seleniumhq.selenium' && details.requested.name != 'htmlunit-driver') {
details.useVersion '3.141.59'
Expand All @@ -38,7 +38,7 @@ configurations.all {
configurations {
integrationTestCompile {
extendsFrom compile

}
integrationTestRuntime {
extendsFrom runtime
Expand Down Expand Up @@ -170,6 +170,7 @@ dependencies {
compile "com.h2database:h2"
runtimeOnly "org.postgresql:postgresql"
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client:2.2.0'
runtimeOnly 'mysql:mysql-connector-java:5.1.48'

//Swagger
compile 'io.springfox:springfox-swagger2:2.9.2'
Expand All @@ -187,7 +188,7 @@ dependencies {
//JSON schema generator
testCompile 'com.kjetland:mbknor-jackson-jsonschema_2.12:1.0.29'
testCompile 'javax.validation:validation-api:2.0.1.Final'

//JSON schema validator
compile 'org.sharegov:mjson:1.4.1'

Expand All @@ -200,7 +201,7 @@ dependencies {
integrationTestCompile "org.springframework.security:spring-security-test"
integrationTestCompile "org.spockframework:spock-core:1.1-groovy-2.4"
integrationTestCompile "org.spockframework:spock-spring:1.1-groovy-2.4"

// CSV file support
compile 'com.opencsv:opencsv:4.4'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public void initRestTemplate() {
}

@PostMapping("/EntityDescriptor")
@Transactional
public ResponseEntity<?> create(@RequestBody EntityDescriptorRepresentation edRepresentation) {
final String entityId = edRepresentation.getEntityId();

Expand All @@ -93,11 +94,13 @@ public ResponseEntity<?> create(@RequestBody EntityDescriptorRepresentation edRe
}

@PostMapping(value = "/EntityDescriptor", consumes = "application/xml")
@Transactional
public ResponseEntity<?> upload(@RequestBody byte[] entityDescriptorXml, @RequestParam String spName) throws Exception {
return handleUploadingEntityDescriptorXml(entityDescriptorXml, spName);
}

@PostMapping(value = "/EntityDescriptor", consumes = "application/x-www-form-urlencoded")
@Transactional
public ResponseEntity<?> upload(@RequestParam String metadataUrl, @RequestParam String spName) throws Exception {
try {
byte[] xmlContents = this.restTemplate.getForObject(metadataUrl, byte[].class);
Expand All @@ -112,6 +115,7 @@ public ResponseEntity<?> upload(@RequestParam String metadataUrl, @RequestParam
}

@PutMapping("/EntityDescriptor/{resourceId}")
@Transactional
public ResponseEntity<?> update(@RequestBody EntityDescriptorRepresentation edRepresentation, @PathVariable String resourceId) {
User currentUser = userService.getCurrentUser();
EntityDescriptor existingEd = entityDescriptorRepository.findByResourceId(resourceId);
Expand Down Expand Up @@ -163,6 +167,7 @@ public ResponseEntity<?> getAll() {
}

@GetMapping("/EntityDescriptor/{resourceId}")
@Transactional(readOnly = true)
public ResponseEntity<?> getOne(@PathVariable String resourceId) {
User currentUser = userService.getCurrentUser();
EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId);
Expand All @@ -180,6 +185,7 @@ public ResponseEntity<?> getOne(@PathVariable String resourceId) {
}

@GetMapping(value = "/EntityDescriptor/{resourceId}", produces = "application/xml")
@Transactional(readOnly = true)
public ResponseEntity<?> getOneXml(@PathVariable String resourceId) throws MarshallingException {
User currentUser = userService.getCurrentUser();
EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId);
Expand All @@ -195,7 +201,7 @@ public ResponseEntity<?> getOneXml(@PathVariable String resourceId) throws Marsh
}
}

@Transactional
@Transactional(readOnly = true)
@GetMapping(value = "/EntityDescriptor/disabledNonAdmin")
public Iterable<EntityDescriptorRepresentation> getDisabledAndNotOwnedByAdmin() {
return entityDescriptorRepository.findAllDisabledAndNotOwnedByAdmin()
Expand All @@ -205,6 +211,7 @@ public Iterable<EntityDescriptorRepresentation> getDisabledAndNotOwnedByAdmin()

@Secured("ROLE_ADMIN")
@DeleteMapping(value = "/EntityDescriptor/{resourceId}")
@Transactional
public ResponseEntity<?> deleteOne(@PathVariable String resourceId) {
EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId);
if (ed == null) {
Expand All @@ -220,6 +227,7 @@ public ResponseEntity<?> deleteOne(@PathVariable String resourceId) {
//Versioning endpoints

@GetMapping("/EntityDescriptor/{resourceId}/Versions")
@Transactional(readOnly = true)
public ResponseEntity<?> getAllVersions(@PathVariable String resourceId) {
EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId);
if (ed == null) {
Expand All @@ -236,6 +244,7 @@ public ResponseEntity<?> getAllVersions(@PathVariable String resourceId) {
}

@GetMapping("/EntityDescriptor/{resourceId}/Versions/{versionId}")
@Transactional(readOnly = true)
public ResponseEntity<?> getSpecificVersion(@PathVariable String resourceId, @PathVariable String versionId) {
EntityDescriptorRepresentation edRepresentation =
versionService.findSpecificVersionOfEntityDescriptor(resourceId, versionId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ public ResponseEntity<?> update(@PathVariable String resourceId, @RequestBody Me
//Versioning endpoints

@GetMapping("/MetadataResolvers/{resourceId}/Versions")
@Transactional(readOnly = true)
public ResponseEntity<?> getAllVersions(@PathVariable String resourceId) {
MetadataResolver resolver = resolverRepository.findByResourceId(resourceId);
if (resolver == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ void prePersist() {
void postLoad() {
this.unknownAttributes.putAll(this.storageAttributeMap);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
import lombok.EqualsAndHashCode;
import org.hibernate.envers.AuditOverride;
import org.hibernate.envers.Audited;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OrderColumn;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -26,13 +23,11 @@ public enum EntityAttributesFilterTargetType {
ENTITY, CONDITION_SCRIPT, CONDITION_REF, REGEX
}

private static Logger LOGGER = LoggerFactory.getLogger(EntityAttributesFilterTarget.class);

private EntityAttributesFilterTargetType entityAttributesFilterTargetType;

@ElementCollection
@OrderColumn
@Column(length = 4000)
@Column(length = 760)
private List<String> value;

public EntityAttributesFilterTargetType getEntityAttributesFilterTargetType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.hibernate.envers.RevisionEntity;

import javax.persistence.Entity;
import javax.persistence.Table;

/**
* Extension of the default envers revision entity to track authenticated principals
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package edu.internet2.tier.shibboleth.admin.ui.hibernate;

import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.model.TypeContributor;
import org.hibernate.service.ServiceRegistry;

import javax.xml.namespace.QName;

public class QNameTypeContributor implements TypeContributor {

@Override
public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
typeContributions.contributeType(new QNameUserType(), "qname", QName.class.getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package edu.internet2.tier.shibboleth.admin.ui.hibernate;

import net.shibboleth.utilities.java.support.xml.QNameSupport;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;

import javax.xml.namespace.QName;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
* Hibernate custom UserType needed to properly persist QName objects.
* Base implementation is taken from {@link https://github.com/tomsontom/emf-databinding-example/blob/0ae7faa67697a84171846852a5c5b0492d9a8f7d/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/QNameUserType.java}
*/
public class QNameUserType implements UserType {

private static final int[] SQL_TYPES = new int[]{Types.VARCHAR};

/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
*/
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}

/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object value) throws HibernateException {
return value;
}

/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
*/
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}

public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true;
} else if (x == null || y == null) {
return false;
} else {
return x.equals(y);
}
}

/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
*/
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}

/**
* Not mutable
*/
public boolean isMutable() {
return false;
}

/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[],
* java.lang.Object)
*/
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor sessionContractImplementor, Object owner) throws HibernateException, SQLException {
final String str = rs.getString(names[0]);
if (rs.wasNull()) {
return null;
}
return convertFromString(str);
}

/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
* java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor sessionContractImplementor) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
st.setString(index, convertToString((QName) value));
}
}

/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object,
* java.lang.Object)
*/
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}

/**
* Returns the parameterizezd enumType
*/
public Class<?> returnedClass() {
return QName.class;
}

/**
* An enum is stored in one varchar
*/
public int[] sqlTypes() {
return SQL_TYPES;
}

protected String convertToString(QName qName) {
return "{" + qName.getNamespaceURI() + "}" + qName.getPrefix() + ":" + qName.getLocalPart();
}

protected QName convertFromString(String str) {
if (str.indexOf("{") == -1) {
throw new HibernateException("String " + str + " can not be converted to a QName, missing starting {");
}
final int endIndexNS = str.indexOf("}");
if (endIndexNS == -1) {
throw new HibernateException("String " + str +
" can not be converted to a QName, missing end ns delimiter } ");
}
final int prefixIndex = str.indexOf(":", endIndexNS);
if (prefixIndex == -1) {
throw new HibernateException("String " + str + " can not be converted to a QName, missing prefix delimiter :");
}
final String ns = str.substring(1, endIndexNS);
final String prefix = str.substring(endIndexNS + 1, prefixIndex);
final String localPart = str.substring(prefixIndex + 1);
return QNameSupport.constructQName(ns, localPart, prefix);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public Role(String name, int rank) {
@Column(unique = true)
private String name;

@Column(name = "ROLE_RANK")
private int rank;

//Ignore properties annotation here is to prevent stack overflow recursive error during JSON serialization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.HashSet;
import java.util.Set;
Expand All @@ -31,6 +32,7 @@
@Setter
@EqualsAndHashCode(callSuper = true, exclude = "roles")
@ToString(exclude = "roles")
@Table(name = "USERS")
public class User extends AbstractAuditable {

@Column(nullable = false, unique = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
edu.internet2.tier.shibboleth.admin.ui.hibernate.QNameTypeContributor
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class MetadataResolverRepositoryTests extends Specification {
basicPersistenceOfResolverIsCorrectFor { it instanceof LocalDynamicMetadataResolver }
}

def "persisting entity attributes filter target with script of more than 255 characters"() {
def "persisting entity attributes filter target with script of 760 max chars, as defied in DB schema mapping"() {
given:
def mdr = new MetadataResolver().with {
it.name = "SHIBUI-1588"
Expand All @@ -211,18 +211,7 @@ class MetadataResolverRepositoryTests extends Specification {
it.resourceId = 'SHIBUI-1588'
it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with {
it.entityAttributesFilterTargetType = CONDITION_SCRIPT
it.singleValue = """
/*
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Cras fermentum odio eu feugiat pretium nibh ipsum. Sed augue lacus viverra vitae.
Fermentum et sollicitudin ac orci. Platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim.
Rhoncus urna neque viverra justo nec ultrices dui sapien. Tortor id aliquet lectus proin nibh nisl condimentum id venenatis.
Massa id neque aliquam vestibulum morbi blandit cursus risus. Metus aliquam eleifend mi in nulla posuere sollicitudin.
Arcu ac tortor dignissim convallis aenean. Et tortor consequat id porta nibh venenatis cras.
Netus et malesuada fames ac turpis egestas. Bibendum arcu vitae elementum curabitur.
Volutpat consequat mauris nunc congue nisi vitae suscipit.
*/
"""
it.singleValue = '/*' + ('X' * 756) + '*/'
it
}
it
Expand Down
Loading

0 comments on commit 29bfc0e

Please sign in to comment.