Skip to content

Commit

Permalink
DCB-194 Add encryption field in the database to fix generation encryp…
Browse files Browse the repository at this point in the history
…ted bundle

(cherry picked from commit 28fe27668781e15f7f1587a3a0ca9c3851005388)
  • Loading branch information
lukasz-andrzejak committed Oct 13, 2023
1 parent 2dd0523 commit dd691fc
Show file tree
Hide file tree
Showing 17 changed files with 196 additions and 54 deletions.
14 changes: 7 additions & 7 deletions LICENSE-THIRD-PARTY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ Lists of 194 third-party dependencies.
(The Apache Software License, Version 2.0) Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava/listenablefuture)
(The Apache Software License, Version 2.0) J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - https://github.com/google/j2objc/)
(The Apache Software License, Version 2.0) project ':json-path' (com.jayway.jsonpath:json-path:2.6.0 - https://github.com/jayway/JsonPath)
(Apache License, Version 2.0) AppStore Bundle Service :: API (com.lgi.appstorebundle:appstore-bundle-service-api:0.16.2-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-api)
(Apache License, Version 2.0) AppStore Bundle Service :: Application (com.lgi.appstorebundle:appstore-bundle-service-application:0.16.2-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-application)
(Apache License, Version 2.0) appstore-metadata-service-client (com.lgi.appstorebundle:appstore-metadata-service-client:0.16.2-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-external/appstore-metadata-service-client)
(Apache License, Version 2.0) client-common (com.lgi.appstorebundle:client-common:0.16.2-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-external/client-common)
(Apache License, Version 2.0) rabbitmq-client (com.lgi.appstorebundle:rabbitmq-client:0.16.2-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-external/rabbitmq-client)
(Apache License, Version 2.0) storage-common (com.lgi.appstorebundle:storage-common:0.16.2-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-storage/storage-common)
(Apache License, Version 2.0) storage-persistent (com.lgi.appstorebundle:storage-persistent:0.16.2-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-storage/storage-persistent)
(Apache License, Version 2.0) AppStore Bundle Service :: API (com.lgi.appstorebundle:appstore-bundle-service-api:0.16.3-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-api)
(Apache License, Version 2.0) AppStore Bundle Service :: Application (com.lgi.appstorebundle:appstore-bundle-service-application:0.16.3-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-application)
(Apache License, Version 2.0) appstore-metadata-service-client (com.lgi.appstorebundle:appstore-metadata-service-client:0.16.3-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-external/appstore-metadata-service-client)
(Apache License, Version 2.0) client-common (com.lgi.appstorebundle:client-common:0.16.3-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-external/client-common)
(Apache License, Version 2.0) rabbitmq-client (com.lgi.appstorebundle:rabbitmq-client:0.16.3-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-external/rabbitmq-client)
(Apache License, Version 2.0) storage-common (com.lgi.appstorebundle:storage-common:0.16.3-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-storage/storage-common)
(Apache License, Version 2.0) storage-persistent (com.lgi.appstorebundle:storage-persistent:0.16.3-SNAPSHOT - https://spring.io/projects/spring-boot/appstore-bundle-service/appstore-bundle-service-storage/storage-persistent)
(ASL 2.0) (GPL v2) (MPL 2.0) RabbitMQ Java Client (com.rabbitmq:amqp-client:5.12.0 - https://www.rabbitmq.com)
(ASL 2.0) (GPL v2) (MPL 2.0) RabbitMQ Java Client (com.rabbitmq:amqp-client:5.13.1 - https://www.rabbitmq.com)
(Eclipse Distribution License - v 1.0) Old JAXB Runtime (com.sun.xml.bind:jaxb-impl:2.3.3 - https://eclipse-ee4j.github.io/jaxb-ri/jaxb-bundles/jaxb-impl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public abstract class Bundle {

public abstract DateTime getMessageTimestamp();

public static Bundle create(UUID id, ApplicationContext applicationContext, BundleStatus status, String xRequestId, DateTime messageTimestamp) {
return new AutoValue_Bundle(id, applicationContext, status, xRequestId, messageTimestamp);
public abstract boolean isEncryptionEnabled();

public static Bundle create(UUID id, ApplicationContext applicationContext, BundleStatus status, String xRequestId, DateTime messageTimestamp, boolean encryptionEnabled) {
return new AutoValue_Bundle(id, applicationContext, status, xRequestId, messageTimestamp, encryptionEnabled);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.lgi.appstorebundle.model.FeedbackMessage;
import com.lgi.appstorebundle.service.BundleService;
import com.lgi.appstorebundle.util.ConsumerFactory;
import com.lgi.appstorebundle.util.EncryptionHelper;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import org.slf4j.Logger;
Expand Down Expand Up @@ -61,6 +62,9 @@ public class RabbitMQConsumersConfiguration {
@Autowired
private ManagedRabbitMQ managedRabbitMQ;

@Autowired
private EncryptionHelper encryptionHelper;

@PostConstruct
public void setUpConsumers() throws IOException {
List<RabbitMQConsumer<RabbitMQConfiguration>> rabbitMQConsumers = List.of(
Expand Down Expand Up @@ -95,7 +99,8 @@ private DeliverCallback decorateBySendingAck(RabbitMQConsumer<RabbitMQConfigurat
private void processGenerationStatus(FeedbackMessage feedbackMessage, String xRequestId) {
process(feedbackMessage, xRequestId, bundleStatus -> {
bundleService.updateBundleStatusIfNewer(feedbackMessage.getId(), bundleStatus, feedbackMessage.getMessageTimestamp());
if (bundleStatus == BundleStatus.GENERATION_COMPLETED && encrypt) {
final boolean isEncryptionEnabled = encryptionHelper.isEncryptionEnabled(feedbackMessage);
if (bundleStatus == BundleStatus.GENERATION_COMPLETED && isEncryptionEnabled) {
bundleService.triggerBundleEncryption(feedbackMessage.getId(), xRequestId);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ public ResponseEntity<Object> startBundleGeneration(@Valid @PathVariable("appId"

if (maybeBundle.filter(IS_NOT_BUNDLE_ERROR).isEmpty()) {
final UUID id = randomUUID();
final boolean encryption = encryptionHelper.isEncryptionEnabled(applicationMetadataForMaintainer);
final boolean isEncryptionEnabled = encryptionHelper.isEncryptionEnabled(applicationMetadataForMaintainer);
LOG.info("Starting a new bundle generation for bundle id:'{}', appId:'{}', appVersion:'{}', platformName:'{}', firmwareVersion:'{}', calculated encryption:'{}'.",
id, appId, appVersion, platformName, firmwareVersion, encryption);
id, appId, appVersion, platformName, firmwareVersion, isEncryptionEnabled);
final BundleContext bundleContext = createBundleContext(id, appId, appVersion, platformName, firmwareVersion,
xRequestId, applicationMetadataForMaintainer.getHeader().getOciImageUrl(), encryption);
xRequestId, applicationMetadataForMaintainer.getHeader().getOciImageUrl(), isEncryptionEnabled);
bundleService.triggerBundleGeneration(bundleContext);
}

Expand All @@ -115,10 +115,10 @@ public ResponseEntity<Object> startBundleGeneration(@Valid @PathVariable("appId"
}

private BundleContext createBundleContext(UUID id, String appId, String appVersion, String platformName,
String firmwareVersion, String xRequestId, String ociImageUrl, boolean encryption) {
String firmwareVersion, String xRequestId, String ociImageUrl, boolean isEncryptionEnabled) {
final DateTime messageTimestamp = now(DateTimeZone.UTC);
final ApplicationContext applicationContext = ApplicationContext.create(appId, appVersion, platformName, firmwareVersion);
final Bundle bundle = Bundle.create(id, applicationContext, GENERATION_REQUESTED, xRequestId, messageTimestamp);
return BundleContext.create(bundle, ociImageUrl, encryption);
final Bundle bundle = Bundle.create(id, applicationContext, GENERATION_REQUESTED, xRequestId, messageTimestamp, isEncryptionEnabled);
return BundleContext.create(bundle, ociImageUrl, isEncryptionEnabled);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,11 @@ public void triggerBundleEncryption(UUID id, String xRequestId) {
});
}, () -> LOG.warn("Could not find a bundle for id '{}', will not send it for encryption.", id));
}

public boolean isEncryptionEnabled(UUID id) {
return bundleDao.isEncryptionEnabled(id).orElseGet(() -> {
LOG.warn("Could not find a bundle for id '{}', will not send it for encryption.", id);
return false;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,32 @@
package com.lgi.appstorebundle.util;

import com.lgi.appstorebundle.external.asms.model.ApplicationMetadataForMaintainer;
import com.lgi.appstorebundle.model.FeedbackMessage;
import com.lgi.appstorebundle.service.BundleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import static com.google.common.base.Preconditions.checkNotNull;

@Component
public class EncryptionHelper {
private boolean encrypt;

private BundleService bundleService;

@Autowired
public EncryptionHelper(@Value("${bundle.encryption.enabled}") boolean encrypt) {
public EncryptionHelper(@Value("${bundle.encryption.enabled}") boolean encrypt, BundleService bundleService) {
this.encrypt = encrypt;
this.bundleService = checkNotNull(bundleService, "bundleService");
}


public boolean isEncryptionEnabled(ApplicationMetadataForMaintainer applicationMetadataForMaintainer) {
return encrypt && Boolean.TRUE.equals(applicationMetadataForMaintainer.getHeader().getEncryption());
}

public boolean isEncryptionEnabled(FeedbackMessage feedbackMessage) {
return encrypt && bundleService.isEncryptionEnabled(feedbackMessage.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ class AppStoreBundleControllerTest {

private static final ApplicationMetadataService ASMS_SERVICE = mock(ApplicationMetadataService.class);
private static final BundleService BUNDLE_SERVICE = mock(BundleService.class);
private static final AppStoreBundleController RESOURCE_ENCRYPTION_ENABLED = new AppStoreBundleController(RETRY_AFTER_IN_SECONDS, ASMS_SERVICE, BUNDLE_SERVICE, new EncryptionHelper(ENCRYPTION_ENABLED));
private static final AppStoreBundleController RESOURCE_ENCRYPTION_DISABLED = new AppStoreBundleController(RETRY_AFTER_IN_SECONDS, ASMS_SERVICE, BUNDLE_SERVICE, new EncryptionHelper(ENCRYPTION_DISABLED));
private static final AppStoreBundleController RESOURCE_ENCRYPTION_ENABLED = new AppStoreBundleController(RETRY_AFTER_IN_SECONDS, ASMS_SERVICE, BUNDLE_SERVICE, new EncryptionHelper(ENCRYPTION_ENABLED, BUNDLE_SERVICE));
private static final AppStoreBundleController RESOURCE_ENCRYPTION_DISABLED = new AppStoreBundleController(RETRY_AFTER_IN_SECONDS, ASMS_SERVICE, BUNDLE_SERVICE, new EncryptionHelper(ENCRYPTION_DISABLED, BUNDLE_SERVICE));
private static final HeaderForMaintainer APPLICATION_HEADER_FOR_MAINTAINER_ENCRYPTION_ENABLED = HeaderForMaintainer.create(APP_ID, APP_NAME, APP_VER, URL, ENCRYPTION_ENABLED, OCI_IMAGE_URL);
private static final HeaderForMaintainer APPLICATION_HEADER_FOR_MAINTAINER_ENCRYPTION_DISABLED = HeaderForMaintainer.create(APP_ID, APP_NAME, APP_VER, URL, ENCRYPTION_DISABLED, OCI_IMAGE_URL);
private static final Header applicationHeader = Header.create(APP_ID, APP_NAME, APP_VER, URL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@
import org.joda.time.DateTimeZone;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

Expand Down Expand Up @@ -68,7 +72,7 @@ class BundleServiceTest {
private final BundleService service = new BundleService(dao, rabbitMQ, encryptionMessageFactory);
private final DateTime messageTimestamp = now(DateTimeZone.UTC);
private final ApplicationContext applicationContext = ApplicationContext.create(APP_ID, APP_VERSION, PLATFORM_NAME, FIRMWARE_VERSION);
private final Bundle bundle = Bundle.create(ID, applicationContext, GENERATION_REQUESTED, X_REQUEST_ID, messageTimestamp);
private final Bundle bundle = Bundle.create(ID, applicationContext, GENERATION_REQUESTED, X_REQUEST_ID, messageTimestamp, true);
private final BundleContext bundleContext = BundleContext.create(bundle, OCI_IMAGE_URL, true);

@Captor
Expand Down Expand Up @@ -149,4 +153,26 @@ void triggerBundleEncryptionWithException_updatesBundleStatusToError() {
verify(rabbitMQ).sendEncryptionMessage(any(), any());
assertEquals(BundleStatus.BUNDLE_ERROR, bundleStatusCaptor.getValue());
}

@ParameterizedTest
@MethodSource
void testEncryption(Boolean dbValue, boolean expectedValue) {
// GIVEN
UUID bundleId = bundle.getId();
when(dao.isEncryptionEnabled(bundleId)).thenReturn(Optional.ofNullable(dbValue));

// WHEN
boolean result = service.isEncryptionEnabled(bundle.getId());

// THEN
assertEquals(expectedValue, result);
}

private static List<Arguments> testEncryption() {
return List.of(
Arguments.of(Boolean.TRUE, true),
Arguments.of(Boolean.FALSE, false),
Arguments.of(null, false)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import com.lgi.appstorebundle.external.asms.model.ApplicationMetadataForMaintainer;
import com.lgi.appstorebundle.external.asms.model.HeaderForMaintainer;
import com.lgi.appstorebundle.model.FeedbackMessage;
import com.lgi.appstorebundle.service.BundleService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
Expand All @@ -29,36 +31,68 @@

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class EncryptionHelperTest {

private final BundleService bundleService = mock(BundleService.class);

@Test
void testEncryptionEnabled() {
void testEncryptionEnabledForApplicationMetadata() {
//GIVEN
EncryptionHelper encryptionHelper = new EncryptionHelper(true);
EncryptionHelper encryptionHelper = new EncryptionHelper(true, bundleService);
ApplicationMetadataForMaintainer applicationMetadataForMaintainer = createMockApplicationMetadataForMaintainer(true);

//WHEN
boolean encryption = encryptionHelper.isEncryptionEnabled(applicationMetadataForMaintainer);
boolean isEncryptionEnabled = encryptionHelper.isEncryptionEnabled(applicationMetadataForMaintainer);

//THEN
assertTrue(isEncryptionEnabled);
}

@Test
void testEncryptionEnabledForFeedbackMessage() {
//GIVEN
EncryptionHelper encryptionHelper = new EncryptionHelper(true, bundleService);
FeedbackMessage feedbackMessage = mock(FeedbackMessage.class);
when(bundleService.isEncryptionEnabled(any())).thenReturn(true);

//WHEN
boolean isEncryptionEnabled = encryptionHelper.isEncryptionEnabled(feedbackMessage);

//THEN
assertTrue(encryption);
assertTrue(isEncryptionEnabled);
}

@ParameterizedTest
@MethodSource
void testEncryptionDisabled(boolean encryptionForHelper, boolean encryptionForMaintainer) {
@MethodSource("testEncryptionDisabled")
void testEncryptionDisabledForApplicationMetadata(boolean encryptionForHelper, boolean encryptionForMaintainer) {
//GIVEN
EncryptionHelper encryptionHelper = new EncryptionHelper(encryptionForHelper);
EncryptionHelper encryptionHelper = new EncryptionHelper(encryptionForHelper, bundleService);
ApplicationMetadataForMaintainer applicationMetadataForMaintainer = createMockApplicationMetadataForMaintainer(encryptionForMaintainer);

//WHEN
boolean encryption = encryptionHelper.isEncryptionEnabled(applicationMetadataForMaintainer);
boolean isEncryptionEnabled = encryptionHelper.isEncryptionEnabled(applicationMetadataForMaintainer);

//THEN
assertFalse(isEncryptionEnabled);
}

@ParameterizedTest
@MethodSource("testEncryptionDisabled")
void testEncryptionDisabledForFeedbackMessage(boolean encryptionForHelper, boolean encryptionForBundle) {
//GIVEN
EncryptionHelper encryptionHelper = new EncryptionHelper(encryptionForHelper, bundleService);
FeedbackMessage feedbackMessage = mock(FeedbackMessage.class);
when(bundleService.isEncryptionEnabled(any())).thenReturn(encryptionForBundle);

//WHEN
boolean isEncryptionEnabled = encryptionHelper.isEncryptionEnabled(feedbackMessage);

//THEN
assertFalse(encryption);
assertFalse(isEncryptionEnabled);
}

private static List<Arguments> testEncryptionDisabled() {
Expand All @@ -69,9 +103,9 @@ private static List<Arguments> testEncryptionDisabled() {
);
}

private ApplicationMetadataForMaintainer createMockApplicationMetadataForMaintainer(boolean encryption) {
private ApplicationMetadataForMaintainer createMockApplicationMetadataForMaintainer(boolean isEncryptionEnabled) {
HeaderForMaintainer headerForMaintainer = mock(HeaderForMaintainer.class);
when(headerForMaintainer.getEncryption()).thenReturn(encryption);
when(headerForMaintainer.getEncryption()).thenReturn(isEncryptionEnabled);

ApplicationMetadataForMaintainer applicationMetadataForMaintainer = mock(ApplicationMetadataForMaintainer.class);
when(applicationMetadataForMaintainer.getHeader()).thenReturn(headerForMaintainer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ class EncryptionMessageFactoryTest {
private static final String X_REQ_ID = "x-request-id-value";
private static final Environment ENV = Environment.DEV;
private static final String BUNDLE_EXTENSION = "tar.gz";
private static final boolean ENCRYPTION_DISABLED = false;

private static final Bundle BUNDLE = Bundle.create(randomUUID(),
ApplicationContext.create("appId", "appVer", "platformName", "firmwareVer"),
BundleStatus.ENCRYPTION_LAUNCHED, X_REQ_ID, DateTime.now(DateTimeZone.UTC));
BundleStatus.ENCRYPTION_LAUNCHED, X_REQ_ID, DateTime.now(DateTimeZone.UTC), ENCRYPTION_DISABLED);

private EncryptionMessageFactory factory;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ public interface BundleDao {

boolean updateBundleStatusIfNewer(UUID id, BundleStatus status, DateTime messageTimestamp);

Optional<Boolean> isEncryptionEnabled(UUID id);

}
Loading

0 comments on commit dd691fc

Please sign in to comment.