Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Certificate Selectable in TestApp #21

Merged
merged 6 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions .run/app_UnitTests.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="app:UnitTests" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value=":app:testDebugUnitTest" />
</list>
</option>
<option name="vmOptions" value="-Dkotest.tags=&quot;Unit&quot;" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
14 changes: 14 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ android {
}
}

tasks.withType<Test>().configureEach {
useJUnitPlatform()

kotlin {
compilerOptions {
// https://youtrack.jetbrains.com/issue/KT-48678/Coroutine-debugger-disable-was-optimised-out-compiler-feature
// We don't want local variables to be optimized out while debugging into tests
freeCompilerArgs.add("-Xdebug")
}
}
}

plugins {
id("com.android.application")
kotlin("plugin.serialization") version "1.9.0"
Expand All @@ -75,6 +87,7 @@ plugins {

dependencies {
implementation(project(":kuksa-sdk"))
testImplementation(project(":test"))

implementation(libs.androidx.appcompat)
implementation(libs.androidx.lifecycle.runtime.ktx)
Expand Down Expand Up @@ -102,4 +115,5 @@ dependencies {
debugImplementation(libs.androidx.compose.ui.tooling.test.manifest)

implementation(libs.androidx.activity.compose)
implementation(libs.androidx.constraintlayout.compose)
}
22 changes: 0 additions & 22 deletions app/src/main/assets/CA.pem

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

package org.eclipse.kuksa.testapp.databroker;

import android.content.res.AssetManager;
import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;
Expand All @@ -34,7 +34,6 @@
import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse;
import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse;
import org.eclipse.kuksa.proto.v1.Types.Datapoint;
import org.eclipse.kuksa.testapp.extension.AssetManagerExtensionKt;
import org.eclipse.kuksa.testapp.model.Certificate;
import org.eclipse.kuksa.testapp.model.ConnectionInfo;
import org.jetbrains.annotations.NotNull;
Expand All @@ -59,24 +58,18 @@ public class JavaDataBrokerEngine implements DataBrokerEngine {
private static final String TAG = JavaDataBrokerEngine.class.getSimpleName();
private static final long TIMEOUT_CONNECTION = 5;

@NonNull
private final AssetManager assetManager;

@Nullable
private DataBrokerConnection dataBrokerConnection = null;

private final Set<DisconnectListener> disconnectListeners = new HashSet<>();

public JavaDataBrokerEngine(@NonNull AssetManager assetManager) {
this.assetManager = assetManager;
}

public void connect(
@NonNull Context context,
@NonNull ConnectionInfo connectionInfo,
@NonNull CoroutineCallback<DataBrokerConnection> callback
) {
if (connectionInfo.isTlsEnabled()) {
connectSecure(connectionInfo, callback);
connectSecure(context, connectionInfo, callback);
} else {
connectInsecure(connectionInfo, callback);
}
Expand All @@ -99,26 +92,27 @@ private void connectInsecure(
}

private void connectSecure(
@NotNull Context context,
@NotNull ConnectionInfo connectInfo,
@NotNull CoroutineCallback<DataBrokerConnection> callback
) {
Certificate rootCert = connectInfo.getCertificate();
Certificate certificate = connectInfo.getCertificate();

ChannelCredentials tlsCredentials = null;
try {
InputStream rootCertFile = AssetManagerExtensionKt.open(assetManager, rootCert);
InputStream rootCertFile = context.getContentResolver().openInputStream(certificate.getUri());
tlsCredentials = TlsChannelCredentials.newBuilder()
.trustManager(rootCertFile)
.build();
} catch (IOException e) {
Log.w(TAG, "Could not find file for certificate: " + rootCert);
Log.w(TAG, "Could not find file for certificate: " + certificate);
}

try {
ManagedChannelBuilder<?> channelBuilder = Grpc
.newChannelBuilderForAddress(connectInfo.getHost(), connectInfo.getPort(), tlsCredentials);

String overrideAuthority = rootCert.getOverrideAuthority().trim();
String overrideAuthority = certificate.getOverrideAuthority().trim();
boolean hasOverrideAuthority = !overrideAuthority.isEmpty();
if (hasOverrideAuthority) {
channelBuilder.overrideAuthority(overrideAuthority);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,16 @@ import org.eclipse.kuksa.testapp.databroker.viewmodel.VSSPropertiesViewModel
import org.eclipse.kuksa.testapp.extension.TAG
import org.eclipse.kuksa.testapp.extension.valueType
import org.eclipse.kuksa.testapp.model.ConnectionInfo
import org.eclipse.kuksa.testapp.preferences.ConnectionInfoRepository
import org.eclipse.kuksa.testapp.ui.theme.KuksaAppAndroidTheme

class KuksaDataBrokerActivity : ComponentActivity() {
private lateinit var connectionInfoRepository: ConnectionInfoRepository

private val topAppBarViewModel: TopAppBarViewModel by viewModels()
private val connectionViewModel: ConnectionViewModel by viewModels()
private val connectionViewModel: ConnectionViewModel by viewModels {
ConnectionViewModel.Factory(connectionInfoRepository)
}
private val vssPropertiesViewModel: VSSPropertiesViewModel by viewModels()
private val outputViewModel: OutputViewModel by viewModels()

Expand All @@ -80,11 +85,11 @@ class KuksaDataBrokerActivity : ComponentActivity() {

private lateinit var dataBrokerEngine: DataBrokerEngine
private val kotlinDataBrokerEngine by lazy {
KotlinDataBrokerEngine(lifecycleScope, assets)
KotlinDataBrokerEngine(lifecycleScope)
}

private val javaDataBrokerEngine by lazy {
JavaDataBrokerEngine(assets)
JavaDataBrokerEngine()
}

override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -101,6 +106,8 @@ class KuksaDataBrokerActivity : ComponentActivity() {
}
}

connectionInfoRepository = ConnectionInfoRepository(this)

dataBrokerEngine = kotlinDataBrokerEngine
topAppBarViewModel.onCompatibilityModeChanged = { isCompatibilityModeEnabled ->
dataBrokerEngine = if (isCompatibilityModeEnabled) {
Expand Down Expand Up @@ -146,7 +153,7 @@ class KuksaDataBrokerActivity : ComponentActivity() {
connectionViewModel.updateConnectionState(ConnectionViewState.CONNECTING)

dataBrokerEngine.registerDisconnectListener(onDisconnectListener)
dataBrokerEngine.connect(connectionInfo, dataBrokerConnectionCallback)
dataBrokerEngine.connect(this, connectionInfo, dataBrokerConnectionCallback)
}

private fun disconnect() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.eclipse.kuksa.testapp.databroker

import android.content.Context
import org.eclipse.kuksa.CoroutineCallback
import org.eclipse.kuksa.DataBrokerConnection
import org.eclipse.kuksa.DisconnectListener
Expand All @@ -32,8 +33,17 @@ import org.eclipse.kuksa.testapp.model.ConnectionInfo
interface DataBrokerEngine {
var dataBrokerConnection: DataBrokerConnection?

fun connect(connectionInfo: ConnectionInfo, callback: CoroutineCallback<DataBrokerConnection>)
fun fetchProperty(property: Property, callback: CoroutineCallback<GetResponse>)
fun connect(
context: Context,
connectionInfo: ConnectionInfo,
callback: CoroutineCallback<DataBrokerConnection>,
)

fun fetchProperty(
property: Property,
callback: CoroutineCallback<GetResponse>,
)

fun updateProperty(
property: Property,
datapoint: Datapoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

package org.eclipse.kuksa.testapp.databroker

import android.content.res.AssetManager
import android.content.Context
import androidx.lifecycle.LifecycleCoroutineScope
import io.grpc.ChannelCredentials
import io.grpc.Grpc
Expand All @@ -38,24 +38,23 @@ import org.eclipse.kuksa.model.Property
import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse
import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse
import org.eclipse.kuksa.proto.v1.Types.Datapoint
import org.eclipse.kuksa.testapp.extension.open
import org.eclipse.kuksa.testapp.model.ConnectionInfo
import java.io.IOException

class KotlinDataBrokerEngine(
private val lifecycleScope: LifecycleCoroutineScope,
private val assetManager: AssetManager,
) : DataBrokerEngine {
override var dataBrokerConnection: DataBrokerConnection? = null

private val disconnectListeners = mutableSetOf<DisconnectListener>()

override fun connect(
context: Context,
connectionInfo: ConnectionInfo,
callback: CoroutineCallback<DataBrokerConnection>,
) {
if (connectionInfo.isTlsEnabled) {
connectSecure(connectionInfo, callback)
connectSecure(context, connectionInfo, callback)
} else {
connectInsecure(connectionInfo, callback)
}
Expand All @@ -78,14 +77,15 @@ class KotlinDataBrokerEngine(
}

private fun connectSecure(
context: Context,
connectInfo: ConnectionInfo,
callback: CoroutineCallback<DataBrokerConnection>,
) {
val rootCert = connectInfo.certificate
val certificate = connectInfo.certificate

val tlsCredentials: ChannelCredentials
try {
val rootCertFile = assetManager.open(rootCert)
val rootCertFile = context.contentResolver.openInputStream(certificate.uri)
tlsCredentials = TlsChannelCredentials.newBuilder()
.trustManager(rootCertFile)
.build()
Expand All @@ -100,7 +100,7 @@ class KotlinDataBrokerEngine(
val channelBuilder = Grpc
.newChannelBuilderForAddress(host, port, tlsCredentials)

val overrideAuthority = rootCert.overrideAuthority.trim()
val overrideAuthority = certificate.overrideAuthority.trim()
val hasOverrideAuthority = overrideAuthority.isNotEmpty()
if (hasOverrideAuthority) {
channelBuilder.overrideAuthority(overrideAuthority)
Expand Down
Loading