Skip to content

Commit

Permalink
433: BALP audit with oauth token support
Browse files Browse the repository at this point in the history
  • Loading branch information
Boris Stanojevic committed Feb 1, 2024
1 parent 7df3541 commit 11e5981
Show file tree
Hide file tree
Showing 56 changed files with 1,489 additions and 107 deletions.
4 changes: 4 additions & 0 deletions boot/ipf-atna-spring-boot-starter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
<groupId>org.openehealth.ipf.commons</groupId>
<artifactId>ipf-commons-audit</artifactId>
</dependency>
<dependency>
<groupId>org.openehealth.ipf.commons</groupId>
<artifactId>ipf-commons-ihe-fhir-r4-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.openehealth.ipf.commons.audit.protocol.AuditTransmissionChannel;
import org.openehealth.ipf.commons.audit.protocol.AuditTransmissionProtocol;
import org.openehealth.ipf.commons.audit.queue.AuditMessageQueue;
import org.openehealth.ipf.commons.ihe.fhir.support.audit.marshal.BalpJsonSerializationStrategy;
import org.openehealth.ipf.commons.ihe.fhir.support.audit.marshal.BalpXmlSerializationStrategy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.security.AbstractAuthenticationAuditListener;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
Expand All @@ -48,7 +50,27 @@ public AuditContext auditContext(IpfAtnaConfigurationProperties config,
AuditExceptionHandler auditExceptionHandler,
AuditMessagePostProcessor auditMessagePostProcessor,
@Value("${spring.application.name}") String appName) {
var auditContext = new DefaultAuditContext();
if (config.getBalp() != null) {
return balpConfiguration(defaultContextConfiguration(new DefaultBalpAuditContext(), config,
auditTransmissionProtocol, auditMessageQueue, tlsParameters, auditMetadataProvider,
auditExceptionHandler, auditMessagePostProcessor, appName), config);
} else {
return defaultContextConfiguration(new DefaultAuditContext(), config, auditTransmissionProtocol,
auditMessageQueue, tlsParameters, auditMetadataProvider, auditExceptionHandler,
auditMessagePostProcessor, appName);
}
}

private <T extends DefaultAuditContext> T defaultContextConfiguration(T auditContext,
IpfAtnaConfigurationProperties config,
AuditTransmissionProtocol auditTransmissionProtocol,
AuditMessageQueue auditMessageQueue,
TlsParameters tlsParameters,
AuditMetadataProvider auditMetadataProvider,
AuditExceptionHandler auditExceptionHandler,
AuditMessagePostProcessor auditMessagePostProcessor,
@Value("${spring.application.name}") String appName) {

auditContext.setAuditEnabled(config.isAuditEnabled());

// Simple properties
Expand All @@ -59,7 +81,6 @@ public AuditContext auditContext(IpfAtnaConfigurationProperties config,
auditContext.setAuditSource(config.getAuditSourceType());
auditContext.setIncludeParticipantsFromResponse(config.isIncludeParticipantsFromResponse());
auditContext.setAuditValueIfMissing(config.getAuditValueIfMissing());
auditContext.setAuditRepositoryContextPath(config.getAuditRepositoryContextPath());

// Strategies and complex parameters; overrideable
auditContext.setTlsParameters(tlsParameters);
Expand All @@ -68,7 +89,60 @@ public AuditContext auditContext(IpfAtnaConfigurationProperties config,
auditContext.setAuditMessageQueue(auditMessageQueue);
auditContext.setAuditExceptionHandler(auditExceptionHandler);
auditContext.setAuditMessagePostProcessor(auditMessagePostProcessor);
return auditContext;
}

private DefaultBalpAuditContext balpConfiguration(DefaultBalpAuditContext auditContext, IpfAtnaConfigurationProperties config) {
if (config.getBalp() != null) {
auditContext.setAuditRepositoryContextPath(config.getBalp().getAuditRepositoryContextPath());
auditContext.setSerializationStrategy(
config.getBalp().getAuditEventSerializationType().equalsIgnoreCase("json")?
new BalpJsonSerializationStrategy() : new BalpXmlSerializationStrategy());
if (config.getBalp().getJwt() != null) {
if (config.getBalp().getJwt().getIdPath() != null) {
auditContext.getBalpJwtExtractorProperties().setIdPath(config.getBalp().getJwt().getIdPath());
}
if (config.getBalp().getJwt().getClientIdPath() != null) {
auditContext.getBalpJwtExtractorProperties().setClientIdPath(config.getBalp().getJwt().getClientIdPath());
}
if (config.getBalp().getJwt().getIssuerPath() != null) {
auditContext.getBalpJwtExtractorProperties().setIssuerPath(config.getBalp().getJwt().getIssuerPath());
}
if (config.getBalp().getJwt().getSubjectPath() != null) {
auditContext.getBalpJwtExtractorProperties().setSubjectPath(config.getBalp().getJwt().getSubjectPath());
}
if (config.getBalp().getJwt().getSubjectNamePath() != null) {
auditContext.getBalpJwtExtractorProperties().setSubjectNamePath(config.getBalp().getJwt().getSubjectNamePath());
}
if (config.getBalp().getJwt().getSubjectRolePath() != null) {
auditContext.getBalpJwtExtractorProperties().setSubjectRolePath(config.getBalp().getJwt().getSubjectRolePath());
}
if (config.getBalp().getJwt().getSubjectOrganizationIdPath() != null) {
auditContext.getBalpJwtExtractorProperties().setSubjectOrganizationIdPath(config.getBalp().getJwt().getSubjectOrganizationIdPath());
}
if (config.getBalp().getJwt().getPurposeOfUsePath() != null) {
auditContext.getBalpJwtExtractorProperties().setPurposeOfUsePath(config.getBalp().getJwt().getPurposeOfUsePath());
}
if (config.getBalp().getJwt().getHomeCommunityIdPath() != null) {
auditContext.getBalpJwtExtractorProperties().setHomeCommunityIdPath(config.getBalp().getJwt().getHomeCommunityIdPath());
}
if (config.getBalp().getJwt().getNationalProviderIdPath() != null) {
auditContext.getBalpJwtExtractorProperties().setNationalProviderIdPath(config.getBalp().getJwt().getNationalProviderIdPath());
}
if (config.getBalp().getJwt().getDocIdPath() != null) {
auditContext.getBalpJwtExtractorProperties().setDocIdPath(config.getBalp().getJwt().getDocIdPath());
}
if (config.getBalp().getJwt().getPatientIdPath() != null) {
auditContext.getBalpJwtExtractorProperties().setPatientIdPath(config.getBalp().getJwt().getPatientIdPath());
}
if (config.getBalp().getJwt().getPersonIdPath() != null) {
auditContext.getBalpJwtExtractorProperties().setPersonIdPath(config.getBalp().getJwt().getPersonIdPath());
}
if (config.getBalp().getJwt().getAcpPath() != null) {
auditContext.getBalpJwtExtractorProperties().setAcpPath(config.getBalp().getJwt().getAcpPath());
}
}
}
return auditContext;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@ public class IpfAtnaConfigurationProperties {
@Getter @Setter
private int auditRepositoryPort = 514;

/**
* Sets the context-path of the BALP audit record repository.
*/
@Getter @Setter
private String auditRepositoryContextPath = "";

/**
* Enterprise Site Id
*/
Expand Down Expand Up @@ -106,4 +100,88 @@ public class IpfAtnaConfigurationProperties {

@Getter @Setter
private String auditValueIfMissing = "UNKNOWN";

@Getter @Setter
private Balp balp;

public static class Balp {

/**
* Sets the context-path of the BALP audit record repository.
*/
@Getter
@Setter
private String auditRepositoryContextPath = "";

@Getter
@Setter
private String auditEventSerializationType = "JSON";

@Getter
@Setter
private Jwt jwt;

public static class Jwt {

@Getter
@Setter
private String[] idPath;

@Getter
@Setter
private String[] issuerPath;

@Getter
@Setter
private String[] clientIdPath;

@Getter
@Setter
private String[] subjectPath;

@Getter
@Setter
private String[] subjectNamePath;

@Getter
@Setter
private String[] subjectOrganizationPath;

@Getter
@Setter
private String[] subjectOrganizationIdPath;

@Getter
@Setter
private String[] subjectRolePath;

@Getter
@Setter
private String[] purposeOfUsePath;

@Getter
@Setter
private String[] homeCommunityIdPath;

@Getter
@Setter
private String[] nationalProviderIdPath;

@Getter
@Setter
private String[] personIdPath;

@Getter
@Setter
private String[] patientIdPath;

@Getter
@Setter
private String[] docIdPath;

@Getter
@Setter
private String[] acpPath;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ public void testAtnaSettings() throws Exception {
assertEquals("mysite", auditContext.getAuditEnterpriseSiteId());
assertEquals("localhost", auditContext.getAuditRepositoryHostName());
assertEquals(1342, auditContext.getAuditRepositoryPort());
assertEquals("fhir", auditContext.getAuditRepositoryContextPath());
assertEquals("TLS", auditContext.getAuditTransmissionProtocol().getTransportName());
assertTrue(auditContext.getAuditMessageQueue() instanceof AsynchronousAuditMessageQueue);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.openehealth.ipf.boot.atna;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.openehealth.ipf.commons.audit.AuditContext;
import org.openehealth.ipf.commons.audit.BalpAuditContext;
import org.openehealth.ipf.commons.audit.queue.AsynchronousAuditMessageQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;


/**
*
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = { TestApplication.class })
@ActiveProfiles("balp")
public class IpfAtnaBalpAutoConfigurationTest {

@Autowired
private AuditContext auditContext;

@Test
public void testAtnaWithBalpSettings() throws Exception {
assertTrue(auditContext instanceof BalpAuditContext);

assertEquals("atna-test", auditContext.getAuditSourceId());
assertEquals("mysite", auditContext.getAuditEnterpriseSiteId());
assertEquals("localhost", auditContext.getAuditRepositoryHostName());
assertEquals(1342, auditContext.getAuditRepositoryPort());
assertEquals("TLS", auditContext.getAuditTransmissionProtocol().getTransportName());
assertTrue(auditContext.getAuditMessageQueue() instanceof AsynchronousAuditMessageQueue);

assertEquals("fhir", ((BalpAuditContext)auditContext).getAuditRepositoryContextPath());
Assertions.assertArrayEquals(new String[]{"cid","client-id","my-client-id-path"},
((BalpAuditContext) auditContext).getBalpJwtExtractorProperties().getClientIdPath());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ipf:
atna:
balp:
audit-repository-context-path: fhir
jwt:
clientIdPath: cid,client-id,my-client-id-path
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ ipf:
audit-enabled: false
audit-repository-host: localhost
audit-repository-port: 1342
audit-repository-context-path: fhir
audit-repository-transport: TLS
audit-enterprise-site-id: mysite
audit-queue-class: org.openehealth.ipf.commons.audit.queue.AsynchronousAuditMessageQueue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,6 @@ default String getAuditValueIfMissing() {
*/
boolean isIncludeParticipantsFromResponse();

String getAuditRepositoryContextPath();

static AuditContext noAudit() {
return DefaultAuditContext.NO_AUDIT;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openehealth.ipf.commons.audit;

/**
* @author Boris Stanojevic
* @since 4.8
*/
public interface BalpAuditContext extends AuditContext {

String getAuditRepositoryContextPath();

BalpJwtExtractorProperties getBalpJwtExtractorProperties();
}
Loading

0 comments on commit 11e5981

Please sign in to comment.