Skip to content

Commit

Permalink
Merge pull request #1827 from nordic-institute/XRDDEV-1689
Browse files Browse the repository at this point in the history
feat: Introduce globalconf V3
  • Loading branch information
andresrosenthal authored Oct 26, 2023
2 parents e14d198 + a456296 commit 0e36a82
Show file tree
Hide file tree
Showing 114 changed files with 5,641 additions and 1,512 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,3 @@ public class ConfigurationSource {
private Set<ConfigurationSigningKey> configurationSigningKeys = new HashSet<>(0);
}


Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import ee.ria.xroad.common.conf.globalconf.GlobalConf;
import ee.ria.xroad.common.conf.globalconf.GlobalGroupInfo;
import ee.ria.xroad.common.conf.globalconf.MemberInfo;
import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType;
import ee.ria.xroad.common.conf.globalconf.SharedParameters;
import ee.ria.xroad.common.identifier.ClientId;
import ee.ria.xroad.common.identifier.GlobalGroupId;
import ee.ria.xroad.common.identifier.SecurityServerId;
Expand Down Expand Up @@ -137,9 +137,9 @@ ClientId getSubjectName(SignCertificateProfileInfoParameters signCertificateProf
String getSecurityServerAddress(SecurityServerId securityServerId);

/**
* {@link GlobalConf#getApprovedTspTypes(String)}
* {@link GlobalConf#getApprovedTsps(String)}
*/
List<ApprovedTSAType> getApprovedTspTypes(String instanceIdentifier);
List<SharedParameters.ApprovedTSA> getApprovedTsps(String instanceIdentifier);

/**
* {@link GlobalConf#isSecurityServerClient(ClientId, SecurityServerId)}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@
*/
package org.niis.xroad.cs.admin.api.service;

import org.niis.xroad.cs.admin.api.domain.ConfigurationSigningKey;
import org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType;
import org.niis.xroad.cs.admin.api.domain.DistributedFile;
import org.niis.xroad.cs.admin.api.dto.ConfigurationParts;
import org.niis.xroad.cs.admin.api.dto.File;
import org.niis.xroad.cs.admin.api.dto.GlobalConfDownloadUrl;

import java.util.List;
import java.util.Map;
import java.util.Set;

public interface ConfigurationService {

Map<String, List<ConfigurationSigningKey>> getNodeAddressesWithConfigurationSigningKeys();

boolean hasSigningKeys(ConfigurationSourceType sourceType);

Set<ConfigurationParts> getConfigurationParts(ConfigurationSourceType sourceType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
package org.niis.xroad.cs.admin.core.entity.mapper;


import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2;
import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor;

import org.mapstruct.Mapper;
import org.niis.xroad.cs.admin.api.converter.GenericUniDirectionalMapper;
Expand All @@ -47,7 +47,7 @@
@Mapper(componentModel = SPRING, unmappedTargetPolicy = ERROR)
public interface TrustedAnchorMapper extends GenericUniDirectionalMapper<TrustedAnchorEntity, TrustedAnchor> {

default TrustedAnchor map(ConfigurationAnchorV2 anchorV2, byte[] anchorBytes) {
default TrustedAnchor map(ConfigurationAnchor anchorV2, byte[] anchorBytes) {
final TrustedAnchor trustedAnchor = new TrustedAnchor();
trustedAnchor.setInstanceIdentifier(anchorV2.getInstanceIdentifier());
trustedAnchor.setGeneratedAt(anchorV2.getGeneratedAt().toInstant());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import ee.ria.xroad.common.conf.globalconf.GlobalConf;
import ee.ria.xroad.common.conf.globalconf.GlobalGroupInfo;
import ee.ria.xroad.common.conf.globalconf.MemberInfo;
import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType;
import ee.ria.xroad.common.conf.globalconf.SharedParameters;
import ee.ria.xroad.common.identifier.ClientId;
import ee.ria.xroad.common.identifier.GlobalGroupId;
import ee.ria.xroad.common.identifier.SecurityServerId;
Expand Down Expand Up @@ -177,10 +177,10 @@ public String getSecurityServerAddress(SecurityServerId securityServerId) {
}

/**
* {@link GlobalConf#getApprovedTspTypes(String)}
* {@link GlobalConf#getApprovedTsps(String)}
*/
public List<ApprovedTSAType> getApprovedTspTypes(String instanceIdentifier) {
return GlobalConf.getApprovedTspTypes(instanceIdentifier);
public List<SharedParameters.ApprovedTSA> getApprovedTsps(String instanceIdentifier) {
return GlobalConf.getApprovedTsps(instanceIdentifier);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public interface ConfigurationSigningKeyRepository extends GenericRepository<Con

List<ConfigurationSigningKeyEntity> findByKeyIdentifierIn(Collection<String> keyIds);

List<ConfigurationSigningKeyEntity> findForSourceIn(List<String> sourceTypes);

void deleteByKeyIdentifier(String identifier);

Optional<ConfigurationSigningKeyEntity> findActiveForSource(String sourceType, String haNodeName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public ConfigurationAnchor recreateAnchor(ConfigurationSourceType configurationT

final var sources = configurationSourceRepository.findAllBySourceType(configurationType.name().toLowerCase());
final var now = TimeUtils.zonedDateTimeNow(ZoneId.of("UTC"));
final var anchorXml = buildAnchorXml(configurationType, instanceIdentifier, now, sources);
final var anchorXml = buildAnchorXml(instanceIdentifier, now, sources);
final var anchorXmlBytes = anchorXml.getBytes(StandardCharsets.UTF_8);
final var anchorXmlHash = CryptoUtils.calculateAnchorHashDelimited(anchorXmlBytes);
if (addAuditLog) {
Expand All @@ -156,8 +156,7 @@ public ConfigurationAnchor recreateAnchor(ConfigurationSourceType configurationT
return new ConfigurationAnchor(anchorXmlHash, now.toInstant());
}

private String buildAnchorXml(final ConfigurationSourceType configurationType,
final String instanceIdentifier,
private String buildAnchorXml(final String instanceIdentifier,
final ZonedDateTime now,
final List<ConfigurationSourceEntity> sources) {
try {
Expand All @@ -171,10 +170,10 @@ private String buildAnchorXml(final ConfigurationSourceType configurationType,
configurationAnchor.setInstanceIdentifier(instanceIdentifier);

sources.stream()
.map(src -> toXmlSource(src, configurationType, factory, false))
.map(src -> toXmlSource(src, factory, false))
.forEach(configurationAnchor.getSource()::add);
sources.stream()
.map(src -> toXmlSource(src, configurationType, factory, true))
.map(src -> toXmlSource(src, factory, true))
.forEach(configurationAnchor.getSource()::add);

JAXBElement<ConfigurationAnchorType> root = factory.createConfigurationAnchor(configurationAnchor);
Expand All @@ -187,9 +186,9 @@ private String buildAnchorXml(final ConfigurationSourceType configurationType,
}
}

private String buildGlobalDownloadUrl(final ConfigurationSourceType sourceType, final String haNodeName, final boolean isHttps) {
private String buildGlobalDownloadUrl(final String sourceType, final String haNodeName, final boolean isHttps) {
final var csAddress = systemParameterService.getCentralServerAddress(haNodeName);
final String sourceDirectory = sourceType.equals(INTERNAL)
final String sourceDirectory = INTERNAL.name().equalsIgnoreCase(sourceType)
? SystemProperties.getCenterInternalDirectory()
: SystemProperties.getCenterExternalDirectory();
final String protocol = isHttps ? "https" : "http";
Expand All @@ -199,12 +198,11 @@ private String buildGlobalDownloadUrl(final ConfigurationSourceType sourceType,

private ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ConfigurationSourceType toXmlSource(
final ConfigurationSourceEntity source,
final ConfigurationSourceType configurationType,
final ObjectFactory factory,
final boolean isHttps) {
final var xmlSource = factory.createConfigurationSourceType();

xmlSource.setDownloadURL(buildGlobalDownloadUrl(configurationType, source.getHaNodeName(), isHttps));
xmlSource.setDownloadURL(buildGlobalDownloadUrl(source.getSourceType(), source.getHaNodeName(), isHttps));
source.getConfigurationSigningKeys().stream()
.map(ConfigurationSigningKeyEntity::getCert)
.forEach(xmlSource.getVerificationCert()::add);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import lombok.SneakyThrows;
import org.niis.xroad.common.exception.NotFoundException;
import org.niis.xroad.common.exception.ServiceException;
import org.niis.xroad.cs.admin.api.domain.ConfigurationSigningKey;
import org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType;
import org.niis.xroad.cs.admin.api.domain.DistributedFile;
import org.niis.xroad.cs.admin.api.dto.ConfigurationParts;
Expand All @@ -47,6 +48,7 @@
import org.niis.xroad.cs.admin.api.service.SystemParameterService;
import org.niis.xroad.cs.admin.core.entity.ConfigurationSourceEntity;
import org.niis.xroad.cs.admin.core.entity.DistributedFileEntity;
import org.niis.xroad.cs.admin.core.entity.mapper.ConfigurationSigningKeyMapper;
import org.niis.xroad.cs.admin.core.entity.mapper.DistributedFileMapper;
import org.niis.xroad.cs.admin.core.repository.ConfigurationSigningKeyRepository;
import org.niis.xroad.cs.admin.core.repository.ConfigurationSourceRepository;
Expand All @@ -59,6 +61,7 @@

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand All @@ -67,6 +70,8 @@
import static ee.ria.xroad.common.conf.globalconf.ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS;
import static ee.ria.xroad.common.conf.globalconf.ConfigurationConstants.FILE_NAME_SHARED_PARAMETERS;
import static ee.ria.xroad.common.util.CryptoUtils.DEFAULT_UPLOAD_FILE_HASH_ALGORITHM;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toSet;
import static org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType.EXTERNAL;
import static org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType.INTERNAL;
Expand Down Expand Up @@ -96,6 +101,21 @@ public class ConfigurationServiceImpl implements ConfigurationService {
private final DistributedFileMapper distributedFileMapper;
private final AuditDataHelper auditDataHelper;
private final ConfigurationPartValidator configurationPartValidator;
private final ConfigurationSigningKeyMapper configurationSigningKeyMapper;

@Override
public Map<String, List<ConfigurationSigningKey>> getNodeAddressesWithConfigurationSigningKeys() {
return configurationSourceRepository.findAll().stream().collect(toMap(
src -> systemParameterService.getCentralServerAddress(src.getHaNodeName()),
src -> src.getConfigurationSigningKeys().stream()
.map(configurationSigningKeyMapper::toTarget)
.collect(toList()),
(signingKeys1, signingKeys2) -> {
signingKeys1.addAll(signingKeys2);
return signingKeys1;
}
));
}

@Override
public boolean hasSigningKeys(final ConfigurationSourceType sourceType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ public void activateKey(final String keyIdentifier) {
}
}

@Override
public Optional<ConfigurationSigningKey> findActiveForSource(String sourceType) {
return configurationSigningKeyRepository.findActiveForSource(sourceType, haConfigStatus.getCurrentHaNodeName())
.map(configurationSigningKeyMapper::toTarget);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*/
package org.niis.xroad.cs.admin.core.service;

import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2;
import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor;
import ee.ria.xroad.common.conf.globalconf.ConfigurationLocation;

import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -91,7 +91,7 @@ public List<TrustedAnchor> findAll() {
@Override
public TrustedAnchor preview(byte[] trustedAnchorFile) {
try {
final ConfigurationAnchorV2 anchorV2 = new ConfigurationAnchorV2(trustedAnchorFile);
final ConfigurationAnchor anchorV2 = new ConfigurationAnchor(trustedAnchorFile);
return trustedAnchorMapper.map(anchorV2, trustedAnchorFile);
} catch (Exception e) {
throw new ValidationFailureException(MALFORMED_ANCHOR);
Expand All @@ -102,7 +102,7 @@ public TrustedAnchor preview(byte[] trustedAnchorFile) {
public TrustedAnchor upload(byte[] trustedAnchor) {
auditDataHelper.calculateAndPutAnchorHash(trustedAnchor);

final ConfigurationAnchorV2 anchorV2 = new ConfigurationAnchorV2(trustedAnchor);
final ConfigurationAnchor anchorV2 = new ConfigurationAnchor(trustedAnchor);

auditDataHelper.put(INSTANCE_IDENTIFIER, anchorV2.getInstanceIdentifier());
auditDataHelper.putDate(GENERATED_AT, anchorV2.getGeneratedAt());
Expand All @@ -116,7 +116,7 @@ public TrustedAnchor upload(byte[] trustedAnchor) {
return trustedAnchorMapper.toTarget(entity);
}

private TrustedAnchorEntity saveTrustedAnchor(ConfigurationAnchorV2 anchorV2, byte[] anchorFile) {
private TrustedAnchorEntity saveTrustedAnchor(ConfigurationAnchor anchorV2, byte[] anchorFile) {
final TrustedAnchorEntity entity = trustedAnchorRepository.findFirstByInstanceIdentifier(anchorV2.getInstanceIdentifier())
.map(existing -> {
anchorUrlRepository.deleteByTrustedAnchorId(existing.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,11 @@ void shouldSuccessfullyRecreateInternal() {
when(configurationSource.getConfigurationSigningKeys())
.thenReturn(new LinkedHashSet<>(List.of(signingKeyEntity1, signingKeyEntity2)));
when(configurationSource.getConfigurationSigningKey()).thenReturn(signingKeyEntity1);
when(configurationSource.getSourceType()).thenReturn(INTERNAL_CONFIGURATION);
when(configurationSource2.getHaNodeName()).thenReturn(HA_NODE_NAME2);
when(configurationSource2.getConfigurationSigningKeys()).thenReturn(Set.of(signingKeyEntity3));
when(configurationSource2.getConfigurationSigningKey()).thenReturn(null);
when(configurationSource2.getSourceType()).thenReturn(INTERNAL_CONFIGURATION);
when(signingKeyEntity1.getCert()).thenReturn(CERT1.getBytes(UTF_8));
when(signingKeyEntity2.getCert()).thenReturn(CERT2.getBytes(UTF_8));
when(signingKeyEntity3.getCert()).thenReturn(CERT3.getBytes(UTF_8));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@
import org.niis.xroad.cs.admin.api.dto.HAConfigStatus;
import org.niis.xroad.cs.admin.api.service.ConfigurationService;
import org.niis.xroad.cs.admin.api.service.SystemParameterService;
import org.niis.xroad.cs.admin.core.entity.ConfigurationSigningKeyEntity;
import org.niis.xroad.cs.admin.core.entity.ConfigurationSourceEntity;
import org.niis.xroad.cs.admin.core.entity.DistributedFileEntity;
import org.niis.xroad.cs.admin.core.entity.mapper.ConfigurationSigningKeyMapper;
import org.niis.xroad.cs.admin.core.entity.mapper.ConfigurationSigningKeyMapperImpl;
import org.niis.xroad.cs.admin.core.entity.mapper.DistributedFileMapper;
import org.niis.xroad.cs.admin.core.entity.mapper.DistributedFileMapperImpl;
import org.niis.xroad.cs.admin.core.repository.ConfigurationSigningKeyRepository;
Expand All @@ -61,6 +64,7 @@
import org.niis.xroad.restapi.config.audit.RestApiAuditProperty;

import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -116,6 +120,8 @@ class ConfigurationServiceImplTest {
private DistributedFileMapper distributedFileMapper = new DistributedFileMapperImpl();
@Mock
private ConfigurationSigningKeyRepository configurationSigningKeyRepository;
@Spy
private final ConfigurationSigningKeyMapper configurationSigningKeyMapper = new ConfigurationSigningKeyMapperImpl();
private ConfigurationServiceImpl configurationServiceHa;

@BeforeEach
Expand Down Expand Up @@ -205,6 +211,17 @@ void shouldReturnEmptyListWhenSourceNotFound() {
assertThat(configurationService.getConfigurationParts(INTERNAL)).isEmpty();
verifyNoInteractions(distributedFileRepository);
}

@Test
void getNodeAddressesWithConfigurationSigningKeys() {
when(configurationSourceRepository.findAll()).thenReturn(List.of(configurationSource, configurationSource));
when(configurationSource.getConfigurationSigningKeys()).thenReturn(Set.of(new ConfigurationSigningKeyEntity()));
when(configurationSource.getHaNodeName()).thenReturn(HA_NODE_NAME);
when(systemParameterService.getCentralServerAddress(HA_NODE_NAME)).thenReturn(CENTRAL_SERVICE);

assertThat(configurationServiceHa.getNodeAddressesWithConfigurationSigningKeys().get(CENTRAL_SERVICE))
.hasSize(2);
}
}

@Nested
Expand Down Expand Up @@ -239,7 +256,8 @@ private ConfigurationServiceImpl createConfigurationService(HAConfigStatus haCon
distributedFileRepository,
distributedFileMapper,
auditDataHelper,
configurationPartValidator);
configurationPartValidator,
configurationSigningKeyMapper);
}

@Nested
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ void uploadNew() throws Exception {
verify(auditDataHelper).calculateAndPutAnchorHash(bytes);
verify(auditDataHelper).put(INSTANCE_IDENTIFIER, "CS0");
verify(auditDataHelper).putDate(GENERATED_AT, anchorDate);
verify(auditDataHelper).put(ANCHOR_URLS, Set.of("http://cs0/internalconf?version=2"));
verify(auditDataHelper).put(ANCHOR_URLS, Set.of("http://cs0/internalconf"));

verify(configurationVerifier).verifyConfiguration(any(), any());

Expand All @@ -164,7 +164,7 @@ void uploadNewVerificationShouldFail() throws Exception {
verify(auditDataHelper).calculateAndPutAnchorHash(bytes);
verify(auditDataHelper).put(INSTANCE_IDENTIFIER, "CS0");
verify(auditDataHelper).putDate(GENERATED_AT, anchorDate);
verify(auditDataHelper).put(ANCHOR_URLS, Set.of("http://cs0/internalconf?version=2"));
verify(auditDataHelper).put(ANCHOR_URLS, Set.of("http://cs0/internalconf"));

verifyNoMoreInteractions(trustedAnchorRepository);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ private void writeFile(Path fileSubPath, byte @NonNull [] data) {
}
}

public int getVersion() {
return version;
}

public Path getVersionSubPath() {
return Path.of("V" + version);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* The MIT License
*
* Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS)
* Copyright (c) 2018 Estonian Information System Authority (RIA),
* Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK)
* Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.niis.xroad.cs.admin.globalconf.generator;

import java.util.List;

public interface ConfigurationPartsGenerator {

int getConfigurationVersion();

List<ConfigurationPart> generateConfigurationParts();
}
Loading

0 comments on commit 0e36a82

Please sign in to comment.