Skip to content

Commit

Permalink
Resolved merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
Gary Thompson committed May 17, 2019
2 parents 51398f4 + 297bdc2 commit d5806c8
Show file tree
Hide file tree
Showing 154 changed files with 7,113 additions and 11,354 deletions.
3 changes: 3 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ dependencies {
compile 'com.opencsv:opencsv:4.4'

testCompile 'org.skyscreamer:jsonassert:1.5.0'

// Envers for persistent entities versioning
compile 'org.hibernate:hibernate-envers'
}

def generatedSrcDir = new File(buildDir, 'generated/src/main/java')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.envers.Audited;

import javax.persistence.Column;
import javax.persistence.Entity;
Expand All @@ -34,6 +35,7 @@
@JsonSubTypes.Type(value=SignatureValidationFilter.class, name="SignatureValidation"),
@JsonSubTypes.Type(value=RequiredValidUntilFilter.class, name="RequiredValidUntil"),
@JsonSubTypes.Type(value=NameIdFormatFilter.class, name="NameIDFormat")})
@Audited
public class MetadataFilter extends AbstractAuditable {

@JsonProperty("@type")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.envers.Audited;

import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers;

import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.envers.AuditOverride;
import org.hibernate.envers.Audited;

import javax.persistence.Embedded;
import javax.persistence.Entity;
Expand All @@ -13,6 +16,8 @@
@Getter
@Setter
@ToString
@Audited
@AuditOverride(forClass = AbstractAuditable.class)
public class FileBackedHttpMetadataResolver extends MetadataResolver {
public FileBackedHttpMetadataResolver() {
type = "FileBackedHttpMetadataResolver";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.envers.Audited;

import javax.persistence.CascadeType;
import javax.persistence.Column;
Expand All @@ -37,6 +38,7 @@
@JsonSubTypes.Type(value = DynamicHttpMetadataResolver.class, name = "DynamicHttpMetadataResolver"),
@JsonSubTypes.Type(value = FilesystemMetadataResolver.class, name = "FilesystemMetadataResolver"),
@JsonSubTypes.Type(value = ResourceBackedMetadataResolver.class, name = "ResourceBackedMetadataResolver")})
@Audited
public class MetadataResolver extends AbstractAuditable {

@JsonProperty("@type")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package edu.internet2.tier.shibboleth.admin.ui.envers;

import lombok.Getter;
import lombok.Setter;
import org.hibernate.envers.DefaultRevisionEntity;
import org.hibernate.envers.RevisionEntity;

import javax.persistence.Entity;

/**
* Extension of the default envers revision entity to track authenticated principals
*/
@Entity
@RevisionEntity(PrincipalEnhancingRevisionListener.class)
@Getter
@Setter
public class PrincipalAwareRevisionEntity extends DefaultRevisionEntity {

private String principalUserName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package edu.internet2.tier.shibboleth.admin.ui.envers;

import org.hibernate.envers.RevisionListener;

import static edu.internet2.tier.shibboleth.admin.ui.security.springsecurity.PrincipalAccessor.currentPrincipalIfLoggedIn;

/**
* Implementation of envers revision listener to enhance revision entity with authenticated principal username.
*/
public class PrincipalEnhancingRevisionListener implements RevisionListener {

private static final String ANONYMOUS = "anonymous";

@Override
public void newRevision(Object revisionEntity) {
PrincipalAwareRevisionEntity rev = (PrincipalAwareRevisionEntity) revisionEntity;
String user = currentPrincipalIfLoggedIn().orElse(ANONYMOUS);
rev.setPrincipalUserName(user);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package edu.internet2.tier.shibboleth.admin.ui.security.springsecurity;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.Optional;

public final class PrincipalAccessor {

//Non-instantiable utility class
private PrincipalAccessor() {
}

public static Optional<String> currentPrincipalIfLoggedIn() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
return Optional.empty();
}
return Optional.of(authentication.getName());
}
}
3 changes: 3 additions & 0 deletions backend/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ spring.jpa.properties.hibernate.format_sql=false

spring.jpa.hibernate.use-new-id-generator-mappings=true

#Envers versioning
spring.jpa.properties.org.hibernate.envers.store_data_at_delete=true

# Set the following property to periodically write out the generated metadata files. There is no default value; the following is just an example
# shibui.metadata-dir=/opt/shibboleth-idp/metadata/generated
shibui.logout-url=/dashboard
Expand Down
12 changes: 12 additions & 0 deletions backend/src/main/resources/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,18 @@ label.email=Email
label.role=Role
label.delete=Delete?

label.metadata-resolver-history=Metadata resolver history
label.metadata-version-history=Metadata Version History
label.select-version=Select Version
label.version=Version
label.save-date=Save Date
label.changed-by=Changed By
label.actions=Actions
label.check-to-select=Check to select
label.current=Current
label.restore=Restore
label.compare-selected=Compare Selected

message.delete-user-title=Delete User?
message.delete-user-body=You are requesting to delete a user. If you complete this process the user will be removed. This cannot be undone. Do you wish to continue?

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

import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration
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.filters.EntityAttributesFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository
import org.hibernate.envers.AuditReaderFactory
import org.hibernate.envers.query.AuditQuery
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.test.context.ContextConfiguration
import org.springframework.transaction.PlatformTransactionManager
import org.springframework.transaction.support.DefaultTransactionDefinition
import spock.lang.Specification

import javax.persistence.EntityManager

import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRES_NEW

/**
* Testing metadata resolvers basic versioning by envers is functioning.
*/
@DataJpaTest
@ContextConfiguration(classes = [CoreShibUiConfiguration, InternationalizationConfiguration, TestConfiguration, SearchConfiguration])
@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"])
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
class MetadataResolverEntityBasicEnversVersioningTests extends Specification {

@Autowired
MetadataResolverRepository metadataResolverRepository

@Autowired
EntityManager entityManager

@Autowired
PlatformTransactionManager txMgr

def "test basic audit and version data is created when persisting base metadata resolver with envers enabled"() {
when:
MetadataResolver mdr = doInExplicitTransaction {
metadataResolverRepository.save(create {new MetadataResolver()})
}
def metadataResolverHistory = resolverHistory()

then:
metadataResolverHistory.size() == 1

when:
def rev = metadataResolverHistory[0]

then:
rev[1].principalUserName == 'anonymous'

when:
mdr.name = 'Updated'
doInExplicitTransaction {
metadataResolverRepository.save(mdr)
}
metadataResolverHistory = resolverHistory()

then:
metadataResolverHistory.size == 2
}

private resolverHistory() {
def auditReader = AuditReaderFactory.get(entityManager)
AuditQuery auditQuery = auditReader
.createQuery()
.forRevisionsOfEntity(MetadataResolver, false, true)
auditQuery.resultList

}

private static create(Closure concreteResolverSupplier) {
MetadataResolver resolver = concreteResolverSupplier()
resolver.with {
it.name = "testme"
it.metadataFilters.add(new EntityAttributesFilter().with {
it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with {
it.entityAttributesFilterTargetType = EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY
it.value = ["hola"]
return it
}
return it
})
}
resolver
}

//This explicit low level transaction dance is required in order to verify history/version data that envers
//writes out only after the explicit transaction is committed, therefore making it impossible to verify within the main tx
//boundary of the test method which commits tx only after an execution of the test method. This let's us explicitly
//start/commit transaction making envers data written out and verifiable
private doInExplicitTransaction(Closure uow) {
def txStatus = txMgr.getTransaction(new DefaultTransactionDefinition(PROPAGATION_REQUIRES_NEW))
def entity = uow()
txMgr.commit(txStatus)
entity
}
}
Loading

0 comments on commit d5806c8

Please sign in to comment.