Skip to content

Commit 1fb7d78

Browse files
committed
improved current user mdc fields for http requests, some refactoring
1 parent 62ff03f commit 1fb7d78

File tree

11 files changed

+228
-153
lines changed

11 files changed

+228
-153
lines changed

dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/authentication/IdentityProviderImpl.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import org.slf4j.LoggerFactory;
1212
import org.springframework.beans.factory.InitializingBean;
1313

14-
import dev.dsf.bpe.service.LocalOrganizationProvider;
14+
import dev.dsf.bpe.service.LocalOrganizationAndEndpointProvider;
1515
import dev.dsf.common.auth.conf.AbstractIdentityProvider;
1616
import dev.dsf.common.auth.conf.Identity;
1717
import dev.dsf.common.auth.conf.IdentityProvider;
@@ -22,27 +22,28 @@ public class IdentityProviderImpl extends AbstractIdentityProvider implements Id
2222
{
2323
private static final Logger logger = LoggerFactory.getLogger(IdentityProviderImpl.class);
2424

25-
private final LocalOrganizationProvider organizationProvider;
25+
private final LocalOrganizationAndEndpointProvider organizationAndEndpointProvider;
2626

27-
public IdentityProviderImpl(RoleConfig roleConfig, LocalOrganizationProvider organizationProvider)
27+
public IdentityProviderImpl(RoleConfig roleConfig,
28+
LocalOrganizationAndEndpointProvider organizationAndEndpointProvider)
2829
{
2930
super(roleConfig);
3031

31-
this.organizationProvider = organizationProvider;
32+
this.organizationAndEndpointProvider = organizationAndEndpointProvider;
3233
}
3334

3435
@Override
3536
public void afterPropertiesSet() throws Exception
3637
{
3738
super.afterPropertiesSet();
3839

39-
Objects.requireNonNull(organizationProvider, "organizationProvider");
40+
Objects.requireNonNull(organizationAndEndpointProvider, "organizationAndEndpointProvider");
4041
}
4142

4243
@Override
4344
protected Optional<Organization> getLocalOrganization()
4445
{
45-
return organizationProvider.getLocalOrganization();
46+
return organizationAndEndpointProvider.getLocalOrganization();
4647
}
4748

4849
@Override
@@ -54,13 +55,15 @@ public Identity getIdentity(X509Certificate[] certificates)
5455
String thumbprint = getThumbprint(certificates[0]);
5556

5657
Optional<Practitioner> practitioner = toPractitioner(certificates[0]);
57-
Optional<Organization> localOrganization = organizationProvider.getLocalOrganization();
58-
if (practitioner.isPresent() && localOrganization.isPresent())
58+
Optional<Organization> localOrganization = organizationAndEndpointProvider.getLocalOrganization();
59+
Optional<Endpoint> localEndpoint = organizationAndEndpointProvider.getLocalEndpoint();
60+
if (practitioner.isPresent() && localOrganization.isPresent() && localEndpoint.isPresent())
5961
{
6062
Practitioner p = practitioner.get();
6163
Organization o = localOrganization.get();
64+
Endpoint e = localEndpoint.get();
6265

63-
return new PractitionerIdentityImpl(o, null, getDsfRolesFor(p, thumbprint, null, null), certificates[0], p,
66+
return new PractitionerIdentityImpl(o, e, getDsfRolesFor(p, thumbprint, null, null), certificates[0], p,
6467
getPractitionerRolesFor(p, thumbprint, null, null), null);
6568
}
6669
else

dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/service/LocalOrganizationProvider.java renamed to dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/service/LocalOrganizationAndEndpointProvider.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
import java.util.Optional;
44

5+
import org.hl7.fhir.r4.model.Endpoint;
56
import org.hl7.fhir.r4.model.Organization;
67

7-
public interface LocalOrganizationProvider
8+
public interface LocalOrganizationAndEndpointProvider
89
{
910
Optional<Organization> getLocalOrganization();
11+
12+
Optional<Endpoint> getLocalEndpoint();
1013
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package dev.dsf.bpe.service;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.temporal.TemporalAmount;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.Objects;
8+
import java.util.Optional;
9+
import java.util.concurrent.atomic.AtomicReference;
10+
11+
import org.hl7.fhir.r4.model.Bundle;
12+
import org.hl7.fhir.r4.model.Endpoint;
13+
import org.hl7.fhir.r4.model.Organization;
14+
import org.slf4j.Logger;
15+
import org.slf4j.LoggerFactory;
16+
import org.springframework.beans.factory.InitializingBean;
17+
18+
import dev.dsf.bpe.client.dsf.ClientProvider;
19+
20+
public class LocalOrganizationAndEndpointProviderImpl implements LocalOrganizationAndEndpointProvider, InitializingBean
21+
{
22+
private static final Logger logger = LoggerFactory.getLogger(LocalOrganizationAndEndpointProviderImpl.class);
23+
24+
private record OrganizationAndEndpoint(Organization organization, Endpoint endpoint)
25+
{
26+
}
27+
28+
private record Entry(Optional<OrganizationAndEndpoint> organizationAndEndpoint, LocalDateTime readTime)
29+
{
30+
}
31+
32+
private final AtomicReference<Entry> entry = new AtomicReference<>();
33+
34+
private final TemporalAmount cacheTimeout;
35+
private final ClientProvider clientProvider;
36+
private final String localEndpointAddress;
37+
38+
public LocalOrganizationAndEndpointProviderImpl(TemporalAmount cacheTimeout, ClientProvider clientProvider,
39+
String localEndpointAddress)
40+
{
41+
this.cacheTimeout = cacheTimeout;
42+
this.clientProvider = clientProvider;
43+
this.localEndpointAddress = localEndpointAddress;
44+
}
45+
46+
@Override
47+
public void afterPropertiesSet() throws Exception
48+
{
49+
Objects.requireNonNull(cacheTimeout, "cacheTimeout");
50+
Objects.requireNonNull(clientProvider, "clientProvider");
51+
Objects.requireNonNull(localEndpointAddress, "localEndpointAddress");
52+
}
53+
54+
@Override
55+
public Optional<Organization> getLocalOrganization()
56+
{
57+
return getLocalOrganizationAndEndpoint().map(OrganizationAndEndpoint::organization);
58+
}
59+
60+
@Override
61+
public Optional<Endpoint> getLocalEndpoint()
62+
{
63+
return getLocalOrganizationAndEndpoint().map(OrganizationAndEndpoint::endpoint);
64+
}
65+
66+
private Optional<OrganizationAndEndpoint> getLocalOrganizationAndEndpoint()
67+
{
68+
Entry e = entry.get();
69+
if (e == null || e.organizationAndEndpoint().isEmpty()
70+
|| LocalDateTime.now().isAfter(e.readTime().plus(cacheTimeout)))
71+
{
72+
Optional<OrganizationAndEndpoint> oAndE = doGetLocalOrganizationAndEndpoint();
73+
if (entry.compareAndSet(e, new Entry(oAndE, LocalDateTime.now())))
74+
return oAndE;
75+
else
76+
return entry.get().organizationAndEndpoint();
77+
}
78+
else
79+
return e.organizationAndEndpoint();
80+
}
81+
82+
private Optional<OrganizationAndEndpoint> doGetLocalOrganizationAndEndpoint()
83+
{
84+
Bundle resultBundle = clientProvider.getWebserviceClient().searchWithStrictHandling(Endpoint.class,
85+
Map.of("status", List.of("active"), "address", List.of(localEndpointAddress), "_include",
86+
List.of("Endpoint:organization")));
87+
88+
if (resultBundle != null && resultBundle.getEntry() != null && resultBundle.getEntry().size() == 2
89+
&& resultBundle.getEntry().get(0).getResource() instanceof Endpoint endpoint
90+
&& resultBundle.getEntry().get(1).getResource() instanceof Organization organization)
91+
{
92+
return Optional.of(new OrganizationAndEndpoint(organization, endpoint));
93+
}
94+
else
95+
{
96+
logger.warn("No active Endpoint/Organization found for address '{}'", localEndpointAddress);
97+
return Optional.empty();
98+
}
99+
}
100+
}

dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/service/LocalOrganizationProviderImpl.java

Lines changed: 0 additions & 102 deletions
This file was deleted.

dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/AuthenticationConfig.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
import dev.dsf.bpe.authentication.BpeServerRole;
1212
import dev.dsf.bpe.authentication.IdentityProviderImpl;
13-
import dev.dsf.bpe.service.LocalOrganizationProvider;
14-
import dev.dsf.bpe.service.LocalOrganizationProviderImpl;
13+
import dev.dsf.bpe.service.LocalOrganizationAndEndpointProvider;
14+
import dev.dsf.bpe.service.LocalOrganizationAndEndpointProviderImpl;
1515
import dev.dsf.common.auth.conf.IdentityProvider;
1616
import dev.dsf.common.auth.conf.RoleConfig;
1717
import dev.dsf.common.auth.conf.RoleConfigReader;
@@ -28,9 +28,9 @@ public class AuthenticationConfig
2828
private PropertiesConfig propertiesConfig;
2929

3030
@Bean
31-
public LocalOrganizationProvider localOrganizationProvider()
31+
public LocalOrganizationAndEndpointProvider localOrganizationProvider()
3232
{
33-
return new LocalOrganizationProviderImpl(Duration.ofSeconds(30), dsfClientConfig.clientProvider(),
33+
return new LocalOrganizationAndEndpointProviderImpl(Duration.ofSeconds(30), dsfClientConfig.clientProvider(),
3434
propertiesConfig.getDsfServerBaseUrl());
3535
}
3636

dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/PractitionerIdentity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public interface PractitionerIdentity extends Identity
1717
*/
1818
Practitioner getPractitioner();
1919

20+
Optional<String> getPractitionerIdentifierValue();
21+
2022
/**
2123
* @return never <code>null</code>
2224
*/

dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/PractitionerIdentityImpl.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ public PractitionerIdentityImpl(Organization organization, Endpoint endpoint,
5757
@Override
5858
public String getName()
5959
{
60-
return getOrganizationIdentifierValue().orElse("?") + "/"
61-
+ getIdentifierValue(practitioner::getIdentifier, PRACTITIONER_IDENTIFIER_SYSTEM).orElse("?");
60+
return getOrganizationIdentifierValue().orElse("?") + "/" + getPractitionerIdentifierValue().orElse("?");
6261
}
6362

6463
@Override
@@ -73,6 +72,12 @@ public Practitioner getPractitioner()
7372
return practitioner;
7473
}
7574

75+
@Override
76+
public Optional<String> getPractitionerIdentifierValue()
77+
{
78+
return getIdentifierValue(practitioner::getIdentifier, PRACTITIONER_IDENTIFIER_SYSTEM);
79+
}
80+
7681
@Override
7782
public Set<Coding> getPractionerRoles()
7883
{

dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/logging/AbstractUserLogger.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33
import java.io.IOException;
44
import java.security.Principal;
55

6-
import org.eclipse.jetty.security.UserPrincipal;
7-
import org.slf4j.Logger;
8-
import org.slf4j.LoggerFactory;
9-
106
import dev.dsf.common.auth.conf.OrganizationIdentity;
117
import dev.dsf.common.auth.conf.PractitionerIdentity;
128
import jakarta.ws.rs.ConstrainedTo;
@@ -21,28 +17,24 @@
2117
@PreMatching
2218
public abstract class AbstractUserLogger implements ContainerRequestFilter, ContainerResponseFilter
2319
{
24-
private static final Logger logger = LoggerFactory.getLogger(AbstractUserLogger.class);
25-
2620
@Override
2721
public final void filter(ContainerRequestContext requestContext) throws IOException
2822
{
2923
Principal principal = requestContext.getSecurityContext().getUserPrincipal();
3024

25+
before(principal);
26+
3127
if (principal instanceof OrganizationIdentity organization)
3228
before(organization);
3329
else if (principal instanceof PractitionerIdentity practitioner)
3430
before(practitioner);
35-
else if (principal instanceof UserPrincipal userPrincipal)
36-
before(userPrincipal);
37-
else
38-
logger.warn("Unknown current user principal of type {}", principal.getClass().getName());
3931
}
4032

4133
protected abstract void before(OrganizationIdentity organization);
4234

4335
protected abstract void before(PractitionerIdentity practitioner);
4436

45-
protected abstract void before(UserPrincipal userPrincipal);
37+
protected abstract void before(Principal userPrincipal);
4638

4739
@Override
4840
public final void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)

dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/logging/CurrentUserLogger.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package dev.dsf.common.auth.logging;
22

3+
import java.security.Principal;
34
import java.util.stream.Collectors;
45

5-
import org.eclipse.jetty.security.UserPrincipal;
66
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
88

@@ -29,8 +29,8 @@ protected void before(PractitionerIdentity practitioner)
2929
}
3030

3131
@Override
32-
protected void before(UserPrincipal userPrincipal)
32+
protected void before(Principal principal)
3333
{
34-
logger.debug("Current identity '{}'", userPrincipal.getName());
34+
logger.debug("Current identity '{}'", principal.getName());
3535
}
3636
}

0 commit comments

Comments
 (0)