Skip to content
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
efebe2f
feat: add the central server connection test to diagnostics page
enelir Oct 6, 2025
42bae78
feat: add the central server connection test to diagnostics page
enelir Oct 7, 2025
0cf0813
feat: add the central server connection test to diagnostics page
enelir Oct 7, 2025
d61d775
feat: add the central server connection test to diagnostics page
enelir Oct 7, 2025
4d3958a
fix: add unit tests
enelir Oct 8, 2025
d47ed2b
fix: test fixes
enelir Oct 8, 2025
676f163
Merge branch 'develop' into XRDDEV-2922
enelir Oct 8, 2025
b06593c
fix: unit test fixes
enelir Oct 8, 2025
5602d9e
fix: checkstyle fix
enelir Oct 8, 2025
fbad83c
fix: test fixes
enelir Oct 8, 2025
a3a85bd
chore: add tests
enelir Oct 9, 2025
759387d
fix: ui fixes
enelir Oct 9, 2025
4ebbb66
fix: tests and translation
enelir Oct 9, 2025
be54284
fix: test and translation
enelir Oct 9, 2025
c3d8c3f
fix: small fixes
enelir Oct 9, 2025
e8d37df
fix: minor fixes
enelir Oct 10, 2025
f03a691
fix: sonar qube issue fixes
enelir Oct 10, 2025
188078b
fix: sonar qube issue
enelir Oct 10, 2025
9a68292
Merge branch 'develop' into XRDDEV-2922
enelir Oct 12, 2025
f1997ad
fix: minor fix
enelir Oct 12, 2025
366ebbe
fix: code review fixes
enelir Oct 14, 2025
150e035
fix: sonar qube issue fixes
enelir Oct 14, 2025
5395b43
fix: translate fixes and code fixes
enelir Oct 16, 2025
f43b4fd
Merge branch 'develop' into XRDDEV-2922
enelir Oct 16, 2025
8e368cc
fix: minor fixes
enelir Oct 16, 2025
8ed62a4
fix: minor fixes
enelir Oct 16, 2025
36374b0
fix: minor fixes
enelir Oct 16, 2025
cf178b3
fix: service name fix
enelir Oct 17, 2025
6809da0
fix: merge develop to XRDDEV-2922 conflict fixes
enelir Oct 17, 2025
52e38cb
fix: name changes
enelir Oct 27, 2025
f491051
Merge branch 'develop' into XRDDEV-2922
enelir Oct 27, 2025
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
Expand Up @@ -31,6 +31,7 @@

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.niis.xroad.common.managementrequest.ManagementRequestSoapExecutor;
import org.niis.xroad.cs.registrationservice.service.AdminApiService;
import org.springframework.http.HttpHeaders;
Expand Down Expand Up @@ -69,6 +70,11 @@ public ResponseEntity<String> register(@RequestHeader(HttpHeaders.CONTENT_TYPE)

log.debug("Making a registration request for {}", authRequest.getServer());

if (BooleanUtils.isTrue(authRequest.isDryRun())) {
log.info("Processed dry-run registration request for {}", authRequest.getServer());
return 0;
}

var requestId = adminApiService.addRegistrationRequest(
authRequest.getServer(),
authRequest.getAddress(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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.common.core.dto;

import ee.ria.xroad.common.DiagnosticStatus;

import lombok.Getter;
import lombok.ToString;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Getter
@ToString
public final class ConnectionStatus implements Serializable {
private final DiagnosticStatus status;
private final String errorCode;
private final List<String> errorMetadata; // empty when OK
private final Map<String, List<String>> validationErrors; // empty when OK

private ConnectionStatus(
DiagnosticStatus status,
String errorCode,
List<String> errorMetadata,
Map<String, List<String>> validationErrors
) {
this.status = status;
this.errorCode = errorCode;
this.errorMetadata = List.copyOf(errorMetadata == null ? List.of() : errorMetadata);
this.validationErrors = validationErrors == null
? Map.of()
: validationErrors.entrySet().stream()
.collect(java.util.stream.Collectors.toUnmodifiableMap(
Map.Entry::getKey,
e -> List.copyOf(e.getValue())
));
}

public static ConnectionStatus ok() {
return new ConnectionStatus(DiagnosticStatus.OK, null, List.of(), Map.of());
}

public static ConnectionStatus error(String errorCode, List<String> metadata) {
return new ConnectionStatus(DiagnosticStatus.ERROR, errorCode,
metadata == null ? List.of() : metadata, Map.of());
}

public static ConnectionStatus errorWithValidation(
String errorCode,
List<String> metadata,
String validationKey,
List<String> validationMetadata
) {
Map<String, List<String>> ve = new HashMap<>();
ve.put(validationKey, validationMetadata == null ? List.of() : List.copyOf(validationMetadata));
return new ConnectionStatus(DiagnosticStatus.ERROR, errorCode,
metadata == null ? List.of() : metadata, ve);
}

public static ConnectionStatus fromErrorAndValidation(
String errorCode,
List<String> metadata,
String validationErrorCode,
List<String> certValidationMetadata) {

if (validationErrorCode == null) {
return ConnectionStatus.error(errorCode, metadata);
}

List<String> validationMeta = (certValidationMetadata == null)
? List.of()
: certValidationMetadata;

return ConnectionStatus.errorWithValidation(
errorCode,
metadata,
validationErrorCode,
validationMeta
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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.common.core.dto;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.Serializable;
import java.util.List;

@Getter
@ToString
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
public final class DownloadUrlConnectionStatus implements Serializable {
private String downloadUrl;
private ConnectionStatus connectionStatus;

private DownloadUrlConnectionStatus(ConnectionStatus connectionStatus, String downloadUrl) {
this.downloadUrl = downloadUrl;
this.connectionStatus = connectionStatus;
}

public static DownloadUrlConnectionStatus ok(String url) {
return new DownloadUrlConnectionStatus(ConnectionStatus.ok(), url);
}

public static DownloadUrlConnectionStatus error(String url, String errorCode, List<String> metadata) {
return new DownloadUrlConnectionStatus(ConnectionStatus.error(errorCode, metadata), url);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* THE SOFTWARE.
*/

package org.niis.xroad.confclient.core;
package org.niis.xroad.common.core.util;

import ee.ria.xroad.common.SystemProperties;

Expand Down
8 changes: 8 additions & 0 deletions src/common/common-domain/src/main/resources/request.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@
</documentation>
</annotation>
</element>
<element name="dryRun" type="boolean" minOccurs="0" default="false">
<annotation>
<documentation>
Optional flag indicating whether the request
should be validated only and not processed like a real request.
</documentation>
</annotation>
</element>
<element name="requestId" type="tns:RequestIdType" minOccurs="0"/>
</sequence>
</complexType>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,15 @@ final class ManagementRequestBuilder {

// -- Public API methods --------------------------------------------------

SoapMessageImpl buildAuthCertRegRequest(SecurityServerId.Conf securityServer, String address, byte[] authCert)
SoapMessageImpl buildAuthCertRegRequest(SecurityServerId.Conf securityServer, String address, byte[] authCert, boolean dryRun)
throws SOAPException, JAXBException, IOException, IllegalAccessException {
log.debug("buildAuthCertRegRequest(server: {}, address: {})", securityServer, address);

var request = FACTORY.createAuthCertRegRequestType();
request.setServer(securityServer);
request.setAddress(address);
request.setAuthCert(authCert);
request.setDryRun(dryRun);

return buildMessage(element(AUTH_CERT_REGISTRATION_REQUEST, AuthCertRegRequestType.class, request));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.niis.xroad.common.core.annotation.ArchUnitSuppressed;
import org.niis.xroad.common.managementrequest.model.AddressChangeRequest;
import org.niis.xroad.common.managementrequest.model.AuthCertRegRequest;
import org.niis.xroad.common.managementrequest.model.AuthCertRegWithoutCertRequest;
import org.niis.xroad.common.managementrequest.model.ClientDisableRequest;
import org.niis.xroad.common.managementrequest.model.ClientEnableRequest;
import org.niis.xroad.common.managementrequest.model.ClientRegRequest;
Expand Down Expand Up @@ -116,14 +117,21 @@ private URI getSecurityServerURI() throws URISyntaxException {
* registered
* @param address the IP address of the security server
* @param authCert the authentication certificate bytes
* @param dryRun if true, the request is not actually processed
* @return request ID in the central server database
* @throws Exception if an error occurs
*/
public Integer sendAuthCertRegRequest(SecurityServerId.Conf securityServer, String address, byte[] authCert)
public Integer sendAuthCertRegRequest(SecurityServerId.Conf securityServer, String address, byte[] authCert, boolean dryRun)
throws Exception {
if (dryRun && authCert.length == 0) {
try (HttpSender sender = managementRequestClient.createCentralHttpSender()) {
return send(sender, getCentralServiceURI(), new AuthCertRegWithoutCertRequest(signerRpcClient, authCert,
securityServer.getOwner(), builder.buildAuthCertRegRequest(securityServer, address, authCert, true)));
}
}
try (HttpSender sender = managementRequestClient.createCentralHttpSender()) {
return send(sender, getCentralServiceURI(), new AuthCertRegRequest(signerRpcClient, authCert, securityServer.getOwner(),
builder.buildAuthCertRegRequest(securityServer, address, authCert)));
builder.buildAuthCertRegRequest(securityServer, address, authCert, dryRun)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ public class AuthCertRegRequest implements ManagementRequest {

private CertificateInfo ownerCert;

private byte[] dataToSign;
private final byte[] dataToSign;

private MultipartOutputStream multipart;
protected MultipartOutputStream multipart;

public AuthCertRegRequest(SignerRpcClient signerRpcClient, byte[] authCert, ClientId owner, SoapMessageImpl request) {
this.signerRpcClient = signerRpcClient;
Expand Down Expand Up @@ -154,7 +154,7 @@ private void writeSignatures() throws IOException, OperatorCreationException {
multipart.write(createSignature(memberSigningInfo.keyId(), ownerSignAlgoId, digest));
}

private void writeSoap() throws IOException {
protected void writeSoap() throws IOException {
multipart.startPart(MimeTypes.TEXT_XML_UTF8);
multipart.write(dataToSign);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.common.managementrequest.model;

import ee.ria.xroad.common.identifier.ClientId;
import ee.ria.xroad.common.message.MultipartOutputStream;
import ee.ria.xroad.common.message.SoapMessageImpl;

import org.niis.xroad.signer.client.SignerRpcClient;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class AuthCertRegWithoutCertRequest extends AuthCertRegRequest {
public AuthCertRegWithoutCertRequest(SignerRpcClient signerRpcClient, byte[] authCert,
ClientId owner,
SoapMessageImpl request) {
super(signerRpcClient, authCert, owner, request);
}

@Override
public InputStream getRequestContent() throws IOException {

ByteArrayOutputStream out = new ByteArrayOutputStream();
multipart = new MultipartOutputStream(out);

writeSoap();

multipart.close();
return new ByteArrayInputStream(out.toByteArray());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ public X509Certificate getCentralServerSslCertificate() {
return null;
}

@Override
public Set<String> findSourceAddresses() {
return Set.of();
}

@Override
public boolean isSecurityServerClient(ClientId client,
SecurityServerId securityServer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ public X509Certificate getCentralServerSslCertificate() {
return globalConfProvider.getCentralServerSslCertificate();
}

@Override
public Set<String> findSourceAddresses() {
return Set.of();
}

@Override
public int getOcspFreshnessSeconds() {
return globalConfProvider.getOcspFreshnessSeconds();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,11 @@ boolean isSecurityServerClient(ClientId client,
*/
X509Certificate getCentralServerSslCertificate();

/**
* @return a set containing all configured source addresses
*/
Set<String> findSourceAddresses();

/**
* @return maximum allowed validity time of OCSP responses. If thisUpdate
* field of an OCSP response is older than ocspFreshnessSeconds seconds,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Set;
import java.util.stream.Collectors;

import static ee.ria.xroad.common.ErrorCodes.X_INTERNAL_ERROR;
import static ee.ria.xroad.common.ErrorCodes.X_OUTDATED_GLOBALCONF;
Expand Down Expand Up @@ -637,6 +638,14 @@ public X509Certificate getCentralServerSslCertificate() {
return certBytes != null ? CryptoUtils.readCertificate(certBytes) : null;
}

@Override
public Set<String> findSourceAddresses() {
return getSharedParameters(getInstanceIdentifier()).getSources().stream()
.map(SharedParameters.ConfigurationSource::getAddress)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
}

@Override
public int getOcspFreshnessSeconds() {
return getSharedParameters(getInstanceIdentifier())
Expand Down
Loading
Loading