Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package dev.dsf.bpe.authentication;

import java.util.stream.Stream;

import dev.dsf.common.auth.conf.DsfRole;
import dev.dsf.common.auth.conf.RoleConfig.RoleKeyAndValues;

public enum BpeServerRole implements DsfRole
{
ADMIN;

public static boolean isValid(String role)
public static BpeServerRole from(RoleKeyAndValues role)
{
return role != null && role.key() != null && !role.key().isBlank() && ADMIN.name().equals(role.key())
&& role.values().isEmpty() ? ADMIN : null;
}

@Override
public boolean matches(DsfRole role)
{
return role != null && !role.isBlank() && Stream.of(values()).map(Enum::name).anyMatch(n -> n.equals(role));
return ADMIN.equals(role);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
import dev.dsf.common.auth.conf.PractitionerIdentityImpl;
import dev.dsf.common.auth.conf.RoleConfig;

public class IdentityProviderImpl extends AbstractIdentityProvider implements IdentityProvider, InitializingBean
public class IdentityProviderImpl extends AbstractIdentityProvider<BpeServerRole>
implements IdentityProvider, InitializingBean
{
private static final Logger logger = LoggerFactory.getLogger(IdentityProviderImpl.class);

private final LocalOrganizationAndEndpointProvider organizationAndEndpointProvider;

public IdentityProviderImpl(RoleConfig roleConfig,
public IdentityProviderImpl(RoleConfig<BpeServerRole> roleConfig,
LocalOrganizationAndEndpointProvider organizationAndEndpointProvider)
{
super(roleConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ public IdentityProvider identityProvider()
}

@Bean
public RoleConfig roleConfig()
public RoleConfig<BpeServerRole> roleConfig()
{
RoleConfig config = new RoleConfigReader().read(propertiesConfig.getRoleConfig(),
role -> BpeServerRole.isValid(role) ? BpeServerRole.valueOf(role) : null, _ -> null);
RoleConfig<BpeServerRole> config = new RoleConfigReader().read(propertiesConfig.getRoleConfig(),
BpeServerRole::from, _ -> null);

logger.info("Role config: {}", config.toString());
return config;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public Set<DsfRole> getDsfRoles()
@Override
public boolean hasDsfRole(DsfRole dsfRole)
{
return dsfRoles.contains(dsfRole);
return dsfRoles.stream().anyMatch(r -> r.matches(dsfRole));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@
import dev.dsf.common.auth.DsfOpenIdCredentials;
import dev.dsf.common.auth.conf.RoleConfig.Mapping;

public abstract class AbstractIdentityProvider implements IdentityProvider, InitializingBean
public abstract class AbstractIdentityProvider<R extends DsfRole> implements IdentityProvider, InitializingBean
{
private static final Logger logger = LoggerFactory.getLogger(AbstractIdentityProvider.class);

private static final String PRACTITIONER_IDENTIFIER_SYSTEM = "http://dsf.dev/sid/practitioner-identifier";

private final RoleConfig roleConfig;
private final RoleConfig<R> roleConfig;
private final Set<String> thumbprints;

public AbstractIdentityProvider(RoleConfig roleConfig)
public AbstractIdentityProvider(RoleConfig<R> roleConfig)
{
this.roleConfig = roleConfig;

Expand Down Expand Up @@ -81,7 +81,7 @@ public final Identity getIdentity(DsfOpenIdCredentials credentials)
List<String> rolesFromTokens = getRolesFromTokens(parsedIdToken, parsedAccessToken);
List<String> groupsFromTokens = getGroupsFromTokens(parsedIdToken, parsedAccessToken);

Set<DsfRole> dsfRoles = getDsfRolesFor(practitioner.get(), null, rolesFromTokens, groupsFromTokens);
Set<R> dsfRoles = getDsfRolesFor(practitioner.get(), null, rolesFromTokens, groupsFromTokens);
Set<Coding> practitionerRoles = getPractitionerRolesFor(practitioner.get(), null, rolesFromTokens,
groupsFromTokens);

Expand Down Expand Up @@ -187,19 +187,18 @@ private List<String> getPropertyArray(Map<String, Object> map, String property)
}

// thumbprint from certificate, token roles and groups from jwt
protected final Set<DsfRole> getDsfRolesFor(Practitioner practitioner, String thumbprint, List<String> tokenRoles,
protected final Set<R> getDsfRolesFor(Practitioner practitioner, String thumbprint, List<String> tokenRoles,
List<String> tokenGroups)
{
List<String> emailAddresses = practitioner.getIdentifier().stream()
.filter(i -> PRACTITIONER_IDENTIFIER_SYSTEM.equals(i.getSystem()) && i.hasValue())
.map(Identifier::getValue).toList();

Stream<DsfRole> r1 = emailAddresses.stream().map(roleConfig::getDsfRolesForEmail).flatMap(List::stream);
Stream<DsfRole> r2 = thumbprint == null ? Stream.empty()
: roleConfig.getDsfRolesForThumbprint(thumbprint).stream();
Stream<DsfRole> r3 = tokenRoles == null ? Stream.empty()
Stream<R> r1 = emailAddresses.stream().map(roleConfig::getDsfRolesForEmail).flatMap(List::stream);
Stream<R> r2 = thumbprint == null ? Stream.empty() : roleConfig.getDsfRolesForThumbprint(thumbprint).stream();
Stream<R> r3 = tokenRoles == null ? Stream.empty()
: tokenRoles.stream().map(roleConfig::getDsfRolesForTokenRole).flatMap(List::stream);
Stream<DsfRole> r4 = tokenGroups == null ? Stream.empty()
Stream<R> r4 = tokenGroups == null ? Stream.empty()
: tokenGroups.stream().map(roleConfig::getDsfRolesForTokenGroup).flatMap(List::stream);

return Stream.of(r1, r2, r3, r4).flatMap(Function.identity()).distinct().collect(Collectors.toSet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,11 @@
public interface DsfRole
{
String name();

/**
* @param role
* may be <code>null</code>
* @return <code>true</code> if same or superset of given <b>role</b>
*/
boolean matches(DsfRole role);
}
Loading