Skip to content

Commit

Permalink
feat(IATP): configurable trusted issuers (eclipse-edc#3603)
Browse files Browse the repository at this point in the history
* feat(IATP): configurable trusted issuers

* pr remarks
  • Loading branch information
wolf4ood authored and Tuncay Tunc (ZF Friedrichshafen AG) committed Nov 15, 2023
1 parent 9752040 commit f703f80
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Trusted Issuer Configuration Extension

This IATP extension makes it possible configure a list of trusted issuers, that will be used matches against the Verifiable Credential issuers.

## Configuration

Per issuer the following settings must be configured. As `<issuer-alias>` any unique string is valid.

| Key | Description | Mandatory |
|:-----------------------------------------------------|:---------------------------------|-----------|
| edc.iam.trusted-issuer.``<issuer-alias>``.id | ID of the issuer. | X |
| edc.iam.trusted-issuer.``<issuer-alias>``.properties | Additional properties of Issuer. | (X) |

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

plugins {
`java-library`
`maven-publish`
}

dependencies {
api(project(":spi:common:identity-trust-spi"))

testImplementation(project(":core:common:junit"))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.identitytrust.issuer.configuration;

import com.fasterxml.jackson.core.type.TypeReference;
import org.eclipse.edc.identitytrust.TrustedIssuerRegistry;
import org.eclipse.edc.identitytrust.model.Issuer;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.system.configuration.Config;
import org.eclipse.edc.spi.types.TypeManager;

import java.util.Map;

import static org.eclipse.edc.identitytrust.issuer.configuration.TrustedIssuerConfigurationExtension.NAME;

@Extension(NAME)
public class TrustedIssuerConfigurationExtension implements ServiceExtension {

public static final String CONFIG_PREFIX = "edc.iam.trusted-issuer";
public static final String PROPERTIES_SUFFIX = "properties";
public static final String ID_SUFFIX = "id";
protected static final String NAME = "Trusted Issuers Configuration Extensions";

@Inject
private TrustedIssuerRegistry trustedIssuerRegistry;
@Inject
private TypeManager typeManager;

@Override
public void initialize(ServiceExtensionContext context) {
var config = context.getConfig(CONFIG_PREFIX);
var issuers = config.partition().map(this::configureIssuer).toList();
if (issuers.isEmpty()) {
throw new EdcException("The list of trusted issuers is empty");
}
issuers.forEach(issuer -> trustedIssuerRegistry.addIssuer(issuer));
}

private Issuer configureIssuer(Config config) {

var id = config.getString(ID_SUFFIX);
var propertiesConfig = config.getString(PROPERTIES_SUFFIX, "{}");
var properties = typeManager.readValue(propertiesConfig, new TypeReference<Map<String, Object>>() {
});
return new Issuer(id, properties);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
#
# Contributors:
# Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
#
#

org.eclipse.edc.identitytrust.issuer.configuration.TrustedIssuerConfigurationExtension
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.identitytrust.issuer.configuration;

import org.eclipse.edc.identitytrust.TrustedIssuerRegistry;
import org.eclipse.edc.identitytrust.model.Issuer;
import org.eclipse.edc.junit.extensions.DependencyInjectionExtension;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.system.configuration.ConfigFactory;
import org.eclipse.edc.spi.types.TypeManager;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;

import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(DependencyInjectionExtension.class)
public class TrustedIssuerConfigurationExtensionTest {

private final TrustedIssuerRegistry trustedIssuerRegistry = mock();

@BeforeEach
void setup(ServiceExtensionContext context) {
context.registerService(TrustedIssuerRegistry.class, trustedIssuerRegistry);
context.registerService(TypeManager.class, new TypeManager());
}

@Test
void initialize(ServiceExtensionContext context, TrustedIssuerConfigurationExtension ext) {
var cfg = ConfigFactory.fromMap(Map.of("issuer1.id", "issuerId1"));
when(context.getConfig("edc.iam.trusted-issuer")).thenReturn(cfg);

ext.initialize(context);

verify(trustedIssuerRegistry).addIssuer(argThat(issuer -> issuer.id().equals("issuerId1")));
}

@Test
void initialize_failure_WithNoIssuer(ServiceExtensionContext context, TrustedIssuerConfigurationExtension ext) {
var cfg = ConfigFactory.fromMap(Map.of());
when(context.getConfig("edc.iam.trusted-issuer")).thenReturn(cfg);

assertThatThrownBy(() -> ext.initialize(context)).isInstanceOf(EdcException.class);
}

@Test
void initialize_withProperties(ServiceExtensionContext context, TrustedIssuerConfigurationExtension ext) {
var properties = "{\"custom\": \"test\"}";
var cfg = ConfigFactory.fromMap(Map.of("issuer1.id", "issuerId1", "issuer1.properties", properties));
when(context.getConfig("edc.iam.trusted-issuer")).thenReturn(cfg);

ext.initialize(context);

verify(trustedIssuerRegistry).addIssuer(argThat(issuer -> issuer.additionalProperties().get("custom").equals("test")));
}

@Test
void initialize_withTwoIssuers(ServiceExtensionContext context, TrustedIssuerConfigurationExtension ext) {
var cfg = ConfigFactory.fromMap(Map.of("issuer1.id", "issuerId1", "issuer2.id", "issuerId2"));
when(context.getConfig("edc.iam.trusted-issuer")).thenReturn(cfg);

ext.initialize(context);

var issuers = ArgumentCaptor.forClass(Issuer.class);

verify(trustedIssuerRegistry, times(2)).addIssuer(issuers.capture());

assertThat(issuers.getAllValues()).hasSize(2)
.extracting(Issuer::id)
.contains("issuerId1", "issuerId2");
}
}
3 changes: 2 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ include(":extensions:common:iam:identity-trust:identity-trust-sts:identity-trust
include(":extensions:common:iam:identity-trust:identity-trust-sts:identity-trust-sts-remote-core")
include(":extensions:common:iam:identity-trust:identity-trust-sts:identity-trust-sts-api")
include(":extensions:common:iam:identity-trust:identity-trust-sts:identity-trust-sts-client-configuration")
include(":extensions:common:iam:identity-trust:identity-trust-issuers-configuration")

include(":extensions:common:json-ld")
include(":extensions:common:metrics:micrometer-core")
Expand Down Expand Up @@ -241,4 +242,4 @@ include(":system-tests:sts-api:sts-api-test-runtime")
include(":system-tests:telemetry:telemetry-test-runner")
include(":system-tests:telemetry:telemetry-test-runtime")

include(":version-catalog")
include(":version-catalog")

0 comments on commit f703f80

Please sign in to comment.