Refactor after review and add tests for extracting by regex
This commit is contained in:
parent
5d84945ccd
commit
fbeb56cf70
@ -100,7 +100,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProvisionResponse provisionDeviceViaX509Chain(DeviceProfile targetProfile, ProvisionRequest provisionRequest) {
|
||||
public ProvisionResponse provisionDeviceViaX509Chain(DeviceProfile targetProfile, ProvisionRequest provisionRequest) throws ProvisionFailedException {
|
||||
if (targetProfile == null) {
|
||||
throw new ProvisionFailedException("Device profile is not specified!");
|
||||
}
|
||||
@ -110,9 +110,10 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
|
||||
X509CertificateChainProvisionConfiguration configuration = (X509CertificateChainProvisionConfiguration) targetProfile.getProfileData().getProvisionConfiguration();
|
||||
String certificateValue = provisionRequest.getCredentialsData().getX509CertHash();
|
||||
String certificateRegEx = configuration.getCertificateRegExPattern();
|
||||
String deviceName = extractDeviceNameFromCertificateCNByRegEx(targetProfile, certificateValue, certificateRegEx);
|
||||
String commonName = getCNFromX509Certificate(certificateValue);
|
||||
String deviceName = extractDeviceNameFromCNByRegEx(targetProfile, commonName, certificateRegEx);
|
||||
if (StringUtils.isBlank(deviceName)) {
|
||||
log.warn("Device name cannot be extracted using regex [{}] for certificate [{}]", certificateRegEx, certificateValue);
|
||||
log.warn("[{}][{}] Failed to extract device name using [{}] and certificate: [{}]", targetProfile.getTenantId(), targetProfile.getId(), certificateRegEx, certificateValue);
|
||||
throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name());
|
||||
}
|
||||
provisionRequest.setDeviceName(deviceName);
|
||||
@ -120,7 +121,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
|
||||
X509CertificateChainProvisionConfiguration x509Configuration = (X509CertificateChainProvisionConfiguration) targetProfile.getProfileData().getProvisionConfiguration();
|
||||
if (targetDevice != null && targetDevice.getDeviceProfileId().equals(targetProfile.getId())) {
|
||||
DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(targetDevice.getTenantId(), targetDevice.getId());
|
||||
if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) {
|
||||
if (DeviceCredentialsType.X509_CERTIFICATE.equals(deviceCredentials.getCredentialsType())) {
|
||||
String updatedDeviceCertificateValue = provisionRequest.getCredentialsData().getX509CertHash();
|
||||
deviceCredentials = updateDeviceCredentials(targetDevice.getTenantId(), deviceCredentials,
|
||||
updatedDeviceCertificateValue, DeviceCredentialsType.X509_CERTIFICATE);
|
||||
@ -295,21 +296,25 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
|
||||
auditLogService.logEntityAction(tenantId, customerId, new UserId(UserId.NULL_UUID), device.getName(), device.getId(), device, actionType, null, provisionRequest);
|
||||
}
|
||||
|
||||
private String extractDeviceNameFromCertificateCNByRegEx(DeviceProfile profile, String x509Value, String regex) {
|
||||
private String getCNFromX509Certificate(String x509Value) {
|
||||
try {
|
||||
String commonName = SslUtil.parseCommonName(SslUtil.readCertFile(x509Value));
|
||||
log.trace("Extract CN [{}] by regex pattern [{}]", commonName, regex);
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(commonName);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
log.trace("[{}][{}] Failed to extract device name using [{}] and certificate: [{}]", profile.getTenantId(), profile.getId(), regex, x509Value);
|
||||
return SslUtil.parseCommonName(SslUtil.readCertFile(x509Value));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String extractDeviceNameFromCNByRegEx(DeviceProfile profile, String commonName, String regex) {
|
||||
try {
|
||||
log.trace("Extract device name from CN [{}] by regex pattern [{}]", commonName, regex);
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(commonName);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
log.trace("[{}][{}] Failed to match device name using [{}] from CN: [{}]", profile.getTenantId(), profile.getId(), regex, commonName);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.ApiUsageState;
|
||||
import org.thingsboard.server.common.data.DataConstants;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.DeviceProfileProvisionType;
|
||||
import org.thingsboard.server.common.data.DeviceTransportType;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.OtaPackage;
|
||||
@ -113,7 +114,6 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.thingsboard.server.common.data.DeviceProfileProvisionType.X509_CERTIFICATE_CHAIN;
|
||||
import static org.thingsboard.server.service.transport.BasicCredentialsValidationResult.PASSWORD_MISMATCH;
|
||||
import static org.thingsboard.server.service.transport.BasicCredentialsValidationResult.VALID;
|
||||
|
||||
@ -246,7 +246,7 @@ public class DefaultTransportApiService implements TransportApiService {
|
||||
return getDeviceInfo(credentials);
|
||||
}
|
||||
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileByProvisionDeviceKey(certificateHash);
|
||||
if (deviceProfile != null && X509_CERTIFICATE_CHAIN.equals(deviceProfile.getProvisionType())) {
|
||||
if (deviceProfile != null && DeviceProfileProvisionType.X509_CERTIFICATE_CHAIN.equals(deviceProfile.getProvisionType())) {
|
||||
String updatedDeviceProvisionSecret = chain.get(0);
|
||||
ProvisionRequest provisionRequest = createProvisionRequest(updatedDeviceProvisionSecret);
|
||||
try {
|
||||
@ -259,7 +259,7 @@ public class DefaultTransportApiService implements TransportApiService {
|
||||
return getEmptyTransportApiResponseFuture();
|
||||
}
|
||||
} else if (deviceProfile != null) {
|
||||
log.warn("[{}] Device Profile provision configuration mismatched: expected {}, actual {}", deviceProfile.getId(), X509_CERTIFICATE_CHAIN, deviceProfile.getProvisionType());
|
||||
log.warn("[{}][{}] Device Profile provision configuration mismatched: expected {}, actual {}", deviceProfile.getTenantId(), deviceProfile.getId(), DeviceProfileProvisionType.X509_CERTIFICATE_CHAIN, deviceProfile.getProvisionType());
|
||||
}
|
||||
}
|
||||
return getEmptyTransportApiResponseFuture();
|
||||
|
||||
@ -0,0 +1,267 @@
|
||||
/**
|
||||
* Copyright © 2016-2023 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.device.provision;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.thingsboard.server.cluster.TbClusterService;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.DeviceProfileProvisionType;
|
||||
import org.thingsboard.server.common.data.Tenant;
|
||||
import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData;
|
||||
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
|
||||
import org.thingsboard.server.common.data.device.profile.X509CertificateChainProvisionConfiguration;
|
||||
import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.security.DeviceCredentials;
|
||||
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
|
||||
import org.thingsboard.server.common.msg.EncryptionUtil;
|
||||
import org.thingsboard.server.common.transport.util.SslUtil;
|
||||
import org.thingsboard.server.dao.attributes.AttributesService;
|
||||
import org.thingsboard.server.dao.audit.AuditLogService;
|
||||
import org.thingsboard.server.dao.device.DeviceCredentialsService;
|
||||
import org.thingsboard.server.dao.device.DeviceProfileService;
|
||||
import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.dao.device.provision.ProvisionFailedException;
|
||||
import org.thingsboard.server.dao.device.provision.ProvisionRequest;
|
||||
import org.thingsboard.server.dao.device.provision.ProvisionResponse;
|
||||
import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
import org.thingsboard.server.queue.TbQueueProducer;
|
||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||
import org.thingsboard.server.queue.discovery.PartitionService;
|
||||
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
|
||||
import org.thingsboard.server.service.device.DeviceProvisionServiceImpl;;import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Slf4j
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = DeviceProvisionServiceImpl.class)
|
||||
public class DeviceProvisionServiceTest {
|
||||
|
||||
|
||||
@MockBean
|
||||
protected TbQueueProducerProvider producerProvider;
|
||||
@MockBean
|
||||
protected TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> ruleEngineMsgProducer;
|
||||
@MockBean
|
||||
protected TbClusterService clusterService;
|
||||
@MockBean
|
||||
protected DeviceProfileService deviceProfileService;
|
||||
@MockBean
|
||||
protected DeviceService deviceService;
|
||||
@MockBean
|
||||
protected DeviceCredentialsService deviceCredentialsService;
|
||||
@MockBean
|
||||
protected AttributesService attributesService;
|
||||
@MockBean
|
||||
protected AuditLogService auditLogService;
|
||||
@MockBean
|
||||
protected PartitionService partitionService;
|
||||
@SpyBean
|
||||
DeviceProvisionServiceImpl service;
|
||||
|
||||
private String[] chain;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
String filePath = "src/test/resources/provision/x509ChainProvisionTest.pem";
|
||||
try {
|
||||
String certificateChain = Files.readString(Paths.get(filePath));
|
||||
certificateChain = certTrimNewLinesForChainInDeviceProfile(certificateChain);
|
||||
chain = fetchLeafCertificateFromChain(certificateChain);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void provisionDeviceViaX509Certificate() {
|
||||
var tenant = createTenant();
|
||||
var deviceProfile = createDeviceProfile(tenant.getId(), chain[1], true);
|
||||
|
||||
var device = createDevice(tenant.getId(), deviceProfile.getId());
|
||||
when(deviceService.findDeviceByTenantIdAndName(any(), any())).thenReturn(device);
|
||||
|
||||
var deviceCredentials = createDeviceCredentials(chain[0], device.getId());
|
||||
when(deviceCredentialsService.findDeviceCredentialsByDeviceId(any(), any())).thenReturn(deviceCredentials);
|
||||
when(deviceCredentialsService.updateDeviceCredentials(any(), any())).thenReturn(deviceCredentials);
|
||||
|
||||
ProvisionResponse response = service.provisionDeviceViaX509Chain(deviceProfile, createProvisionRequest(chain[0]));
|
||||
|
||||
verify(deviceService, times(1)).findDeviceByTenantIdAndName(any(), any());
|
||||
verify(deviceCredentialsService, times(1)).findDeviceCredentialsByDeviceId(any(), any());
|
||||
verify(deviceCredentialsService, times(1)).updateDeviceCredentials(any(), any());
|
||||
|
||||
Assertions.assertThat(response.getResponseStatus()).isEqualTo(ProvisionResponseStatus.SUCCESS);
|
||||
Assertions.assertThat(response.getDeviceCredentials()).isEqualTo(deviceCredentials);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void provisionDeviceWithIncorrectConfiguration() {
|
||||
var tenant = createTenant();
|
||||
var deviceProfile = createDeviceProfile(tenant.getId(), chain[1], false);
|
||||
|
||||
Assertions.assertThatThrownBy(() ->
|
||||
service.provisionDeviceViaX509Chain(deviceProfile, createProvisionRequest(chain[0])))
|
||||
.isInstanceOf(ProvisionFailedException.class);
|
||||
|
||||
verify(deviceService, times(1)).findDeviceByTenantIdAndName(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchDeviceNameFromX509CNCertificateByRegex() {
|
||||
var tenant = createTenant();
|
||||
var deviceProfile = createDeviceProfile(tenant.getId(), chain[1], true);
|
||||
X509CertificateChainProvisionConfiguration configuration = (X509CertificateChainProvisionConfiguration) deviceProfile.getProfileData().getProvisionConfiguration();
|
||||
String CN = getCNFromX509Certificate(chain[0]);
|
||||
String deviceName = service.extractDeviceNameFromCNByRegEx(deviceProfile, CN, configuration.getCertificateRegExPattern());
|
||||
|
||||
Assertions.assertThat(deviceName).isNotBlank();
|
||||
Assertions.assertThat(deviceName).isEqualTo("deviceCertificate");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchDeviceNameFromCNByRegex() {
|
||||
var CN = "DeviceA.company.com";
|
||||
var regex = "(.*)\\.company.com";
|
||||
var result = service.extractDeviceNameFromCNByRegEx(null, CN, regex);
|
||||
Assertions.assertThat(result).isNotBlank();
|
||||
Assertions.assertThat(result).isEqualTo("DeviceA");
|
||||
|
||||
CN = "DeviceA@company.com";
|
||||
regex = "(.*)@company.com";
|
||||
result = service.extractDeviceNameFromCNByRegEx(null, CN, regex);
|
||||
Assertions.assertThat(result).isNotBlank();
|
||||
Assertions.assertThat(result).isEqualTo("DeviceA");
|
||||
|
||||
CN = "prefixDeviceAsuffix@company.com";
|
||||
regex = "prefix(.*)suffix@company.com";
|
||||
result = service.extractDeviceNameFromCNByRegEx(null, CN, regex);
|
||||
Assertions.assertThat(result).isNotBlank();
|
||||
Assertions.assertThat(result).isEqualTo("DeviceA");
|
||||
|
||||
CN = "prefixDeviceAsufix@company.com";
|
||||
regex = "prefix(.*)sufix@company.com";
|
||||
result = service.extractDeviceNameFromCNByRegEx(null, CN, regex);
|
||||
Assertions.assertThat(result).isNotBlank();
|
||||
Assertions.assertThat(result).isEqualTo("DeviceA");
|
||||
|
||||
CN = "region.DeviceA.220423@company.com";
|
||||
regex = "\\D+\\.(.*)\\.\\d+@company.com";
|
||||
result = service.extractDeviceNameFromCNByRegEx(null, CN, regex);
|
||||
Assertions.assertThat(result).isNotBlank();
|
||||
Assertions.assertThat(result).isEqualTo("DeviceA");
|
||||
}
|
||||
|
||||
private DeviceProfile createDeviceProfile(TenantId tenantId, String certificateValue, boolean isAllowToCreateNewDevices) {
|
||||
X509CertificateChainProvisionConfiguration provision = new X509CertificateChainProvisionConfiguration();
|
||||
provision.setProvisionDeviceSecret(certificateValue);
|
||||
provision.setCertificateRegExPattern("([^@]+)");
|
||||
provision.setAllowCreateNewDevicesByX509Certificate(isAllowToCreateNewDevices);
|
||||
|
||||
DeviceProfileData deviceProfileData = new DeviceProfileData();
|
||||
deviceProfileData.setProvisionConfiguration(provision);
|
||||
|
||||
DeviceProfile deviceProfile = new DeviceProfile();
|
||||
deviceProfile.setId(new DeviceProfileId(UUID.randomUUID()));
|
||||
deviceProfile.setProfileData(deviceProfileData);
|
||||
deviceProfile.setProvisionDeviceKey(EncryptionUtil.getSha3Hash(certificateValue));
|
||||
deviceProfile.setProvisionType(DeviceProfileProvisionType.X509_CERTIFICATE_CHAIN);
|
||||
deviceProfile.setTenantId(tenantId);
|
||||
return deviceProfile;
|
||||
}
|
||||
|
||||
private Device createDevice(TenantId tenantId, DeviceProfileId deviceProfileId) {
|
||||
Device device = new Device();
|
||||
device.setTenantId(tenantId);
|
||||
device.setId(new DeviceId(UUID.randomUUID()));
|
||||
device.setDeviceProfileId(deviceProfileId);
|
||||
device.setCustomerId(new CustomerId(UUID.randomUUID()));
|
||||
return device;
|
||||
}
|
||||
|
||||
private Tenant createTenant() {
|
||||
Tenant tenant = new Tenant();
|
||||
tenant.setId(new TenantId(UUID.randomUUID()));
|
||||
return tenant;
|
||||
}
|
||||
|
||||
private DeviceCredentials createDeviceCredentials(String certificateValue, DeviceId deviceId) {
|
||||
DeviceCredentials deviceCredentials = new DeviceCredentials();
|
||||
deviceCredentials.setDeviceId(deviceId);
|
||||
deviceCredentials.setCredentialsValue(certificateValue);
|
||||
deviceCredentials.setCredentialsId(EncryptionUtil.getSha3Hash(certificateValue));
|
||||
deviceCredentials.setCredentialsType(DeviceCredentialsType.X509_CERTIFICATE);
|
||||
return deviceCredentials;
|
||||
}
|
||||
|
||||
private ProvisionRequest createProvisionRequest(String certificateValue) {
|
||||
return new ProvisionRequest(null, DeviceCredentialsType.X509_CERTIFICATE,
|
||||
new ProvisionDeviceCredentialsData(null, null, null, null, certificateValue),
|
||||
null);
|
||||
}
|
||||
|
||||
public static String certTrimNewLinesForChainInDeviceProfile(String input) {
|
||||
return input.replaceAll("\n", "")
|
||||
.replaceAll("\r", "")
|
||||
.replaceAll("-----BEGIN CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n")
|
||||
.replaceAll("-----END CERTIFICATE-----", "\n-----END CERTIFICATE-----\n")
|
||||
.trim();
|
||||
}
|
||||
|
||||
private String[] fetchLeafCertificateFromChain(String value) {
|
||||
List<String> chain = new ArrayList<>();
|
||||
String regex = "-----BEGIN CERTIFICATE-----\\s*.*?\\s*-----END CERTIFICATE-----";
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(value);
|
||||
while (matcher.find()) {
|
||||
chain.add(matcher.group(0));
|
||||
}
|
||||
return chain.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private String getCNFromX509Certificate(String x509Value) {
|
||||
try {
|
||||
return SslUtil.parseCommonName(SslUtil.readCertFile(x509Value));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,7 +109,8 @@ public class DefaultTransportApiServiceTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
String filePath = "src/test/resources/mqtt/x509ChainProvisionTest.pem";
|
||||
|
||||
String filePath = "src/test/resources/provision/x509ChainProvisionTest.pem";
|
||||
try {
|
||||
certificateChain = Files.readString(Paths.get(filePath));
|
||||
certificateChain = certTrimNewLinesForChainInDeviceProfile(certificateChain);
|
||||
@ -120,7 +121,7 @@ public class DefaultTransportApiServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateExistingDeviceX509Certificate() {
|
||||
public void validateExistingDeviceByX509CertificateStrategy() {
|
||||
var device = createDevice();
|
||||
when(deviceService.findDeviceByIdAsync(any(), any())).thenReturn(Futures.immediateFuture(device));
|
||||
|
||||
@ -145,13 +146,13 @@ public class DefaultTransportApiServiceTest {
|
||||
when(deviceCredentialsService.updateDeviceCredentials(any(), any())).thenReturn(deviceCredentials);
|
||||
|
||||
var provisionResponse = createProvisionResponse(deviceCredentials);
|
||||
when(deviceProvisionService.provisionDevice(any())).thenReturn(provisionResponse);
|
||||
when(deviceProvisionService.provisionDeviceViaX509Chain(any(), any())).thenReturn(provisionResponse);
|
||||
|
||||
service.validateOrCreateDeviceX509Certificate(certificateChain);
|
||||
verify(deviceProfileService, times(1)).findDeviceProfileByProvisionDeviceKey(any());
|
||||
verify(deviceService, times(1)).findDeviceByIdAsync(any(), any());
|
||||
verify(deviceCredentialsService, times(1)).findDeviceCredentialsByCredentialsId(any());
|
||||
verify(deviceProvisionService, times(1)).provisionDevice(any());
|
||||
verify(deviceProvisionService, times(1)).provisionDeviceViaX509Chain(any(), any());
|
||||
}
|
||||
|
||||
private DeviceProfile createDeviceProfile(String certificateValue) {
|
||||
|
||||
@ -24,5 +24,5 @@ public interface DeviceProvisionService {
|
||||
|
||||
ProvisionResponse provisionDevice(ProvisionRequest provisionRequest) throws ProvisionFailedException;
|
||||
|
||||
ProvisionResponse provisionDeviceViaX509Chain(DeviceProfile deviceProfile, ProvisionRequest provisionRequest);
|
||||
ProvisionResponse provisionDeviceViaX509Chain(DeviceProfile deviceProfile, ProvisionRequest provisionRequest) throws ProvisionFailedException;
|
||||
}
|
||||
|
||||
@ -408,8 +408,8 @@ public class DeviceProfileDataValidator extends AbstractHasOtaPackageValidator<D
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
log.trace("Failed to validate certificate due to: ", ignored);
|
||||
} catch (Exception e) {
|
||||
log.trace("Failed to validate certificate due to: ", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,15 +1,21 @@
|
||||
#### Examples of RegEx usage
|
||||
|
||||
* **Pattern:** <code>.*</code> - matches any character (until line terminators)
|
||||
<br>**CN sample:** <code>DeviceName\nAdditionalInfo</code>
|
||||
<br>**Pattern matches:** <code>DeviceName</code>
|
||||
The regular expression is required to extract device name from the X509 certificate's common name.
|
||||
The regular expression syntax is based on Java [Pattern](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html).
|
||||
You may also use this [resource](https://regex101.com/) to test your expressions but make sure you select Java 8 flavor.
|
||||
|
||||
* **Pattern:** <code>^([^@]+)</code> - matches any string that starts with one or more characters that are not the <code>@</code> symbol (<code>@</code> could be replaced by any other symbol)
|
||||
<br>**CN sample:** <code>DeviceName@AdditionalInfo</code>
|
||||
<br>**Pattern matches:** <code>DeviceName</code>
|
||||
* **Pattern:**<code>(.*)\.company.com</code>- matches any characters before the ".company.com".
|
||||
<br>**CN sample:**<code>DeviceA.company.com</code>
|
||||
<br>**Result:**<code>DeviceA</code>
|
||||
|
||||
* **Pattern:** <code>[\w]*$</code> (equivalent to <code>[a-zA-Z0-9_]\*$</code>) - matches zero or more occurences of any word character (letter, digit or underscore) at the end of the string
|
||||
<br>**CN sample:** <code>AdditionalInfo2110#DeviceName_01</code>
|
||||
<br>**Pattern matches:** <code>DeviceName_01</code>
|
||||
* **Pattern:** <code>(.*)@company.com</code>- matches any characters before the "@company.com".
|
||||
<br>**CN sample:**<code>DeviceA@company.com</code>
|
||||
<br>**Result:**<code>DeviceA</code>
|
||||
|
||||
**Note:** Client will get error response in case regex is failed to match.
|
||||
* **Pattern:** <code>prefix(.*)suffix@company.com</code>- matches characters between "prefix" and "suffix@company.com".
|
||||
<br>**CN sample:**<code>prefixDeviceAsuffix@company.com</code>
|
||||
<br>**Pattern matches:** <code>DeviceA</code>
|
||||
|
||||
* **Pattern:** <code>\\D+\\.(.*)\\.\\d+@company.com</code>- matches characters between not digits prefix followed by period and sequence of digits with "@company.com" ending.
|
||||
<br>**CN sample:**<code>region.DeviceA.220423@company.com</code>
|
||||
<br>**Pattern matches:** <code>DeviceA</code>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user