From 1d4ff54278e6d4ede864480b389cec1c17db1766 Mon Sep 17 00:00:00 2001 From: Andre Weber Date: Wed, 21 Feb 2024 07:46:06 +0100 Subject: [PATCH 1/8] feature(SDK): Add Support for Authentication closes: #76 --- .../org/eclipse/kuksa/DataBrokerConnection.kt | 12 +++++ .../org/eclipse/kuksa/DataBrokerConnector.kt | 5 ++ .../eclipse/kuksa/DataBrokerTransporter.kt | 20 ++++++-- .../kuksa/authentication/JsonWebToken.kt | 43 ++++++++++++++++ .../kuksa/authentication/VALStubExtension.kt | 50 +++++++++++++++++++ 5 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/JsonWebToken.kt create mode 100644 kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/VALStubExtension.kt diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt index 8c4aacf9..ee7db7f9 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt @@ -25,6 +25,7 @@ import io.grpc.ManagedChannel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.eclipse.kuksa.authentication.JsonWebToken import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.extension.datapoint @@ -40,6 +41,7 @@ import org.eclipse.kuksa.vsscore.model.VssProperty import org.eclipse.kuksa.vsscore.model.VssSpecification import org.eclipse.kuksa.vsscore.model.heritage import org.eclipse.kuksa.vsscore.model.vssProperties +import kotlin.properties.Delegates /** * The DataBrokerConnection holds an active connection to the DataBroker. The Connection can be use to interact with the @@ -54,8 +56,18 @@ class DataBrokerConnection internal constructor( ), private val dataBrokerSubscriber: DataBrokerSubscriber = DataBrokerSubscriber(dataBrokerTransporter), ) { + /** + * Used to register and unregister multiple [DisconnectListener]. + */ val disconnectListeners = MultiListener() + /** + * A JsonWebToken can be provided to authenticate against the DataBroker. + */ + var jsonWebToken: JsonWebToken? by Delegates.observable(null) { _, _, newValue -> + dataBrokerTransporter.jsonWebToken = newValue + } + init { val state = managedChannel.getState(false) managedChannel.notifyWhenStateChanged(state) { diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnector.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnector.kt index 565f84ac..9d885395 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnector.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnector.kt @@ -26,6 +26,7 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.withContext +import org.eclipse.kuksa.authentication.JsonWebToken import org.eclipse.kuksa.extension.TAG /** @@ -34,6 +35,7 @@ import org.eclipse.kuksa.extension.TAG */ class DataBrokerConnector @JvmOverloads constructor( private val managedChannel: ManagedChannel, + private val jsonWebToken: JsonWebToken? = null, private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default, ) { @@ -73,6 +75,9 @@ class DataBrokerConnector @JvmOverloads constructor( if (state == ConnectivityState.READY) { return@withContext DataBrokerConnection(managedChannel, defaultDispatcher) + .apply { + jsonWebToken = this@DataBrokerConnector.jsonWebToken + } } else { managedChannel.shutdownNow() throw DataBrokerException("timeout") diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerTransporter.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerTransporter.kt index 554ca496..f6d3482b 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerTransporter.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerTransporter.kt @@ -28,6 +28,8 @@ import io.grpc.stub.StreamObserver import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.eclipse.kuksa.authentication.JsonWebToken +import org.eclipse.kuksa.authentication.withAuthenticationInterceptor import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.extension.applyDatapoint import org.eclipse.kuksa.proto.v1.KuksaValV1 @@ -49,6 +51,7 @@ internal class DataBrokerTransporter( private val managedChannel: ManagedChannel, private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default, ) { + init { val state = managedChannel.getState(false) check(state == ConnectivityState.READY) { @@ -56,6 +59,11 @@ internal class DataBrokerTransporter( } } + /** + * A JsonWebToken can be provided to authenticate against the DataBroker. + */ + var jsonWebToken: JsonWebToken? = null + /** * Sends a request to the DataBroker to respond with the specified [vssPath] and [fields] values. * @@ -76,7 +84,9 @@ internal class DataBrokerTransporter( .build() return@withContext try { - blockingStub.get(request) + blockingStub + .withAuthenticationInterceptor(jsonWebToken) + .get(request) } catch (e: StatusRuntimeException) { throw DataBrokerException(e.message, e) } @@ -114,7 +124,9 @@ internal class DataBrokerTransporter( .build() return@withContext try { - blockingStub.set(request) + blockingStub + .withAuthenticationInterceptor(jsonWebToken) + .set(request) } catch (e: StatusRuntimeException) { throw DataBrokerException(e.message, e) } @@ -171,7 +183,9 @@ internal class DataBrokerTransporter( cancellableContext.run { try { - asyncStub.subscribe(request, streamObserver) + asyncStub + .withAuthenticationInterceptor(jsonWebToken) + .subscribe(request, streamObserver) } catch (e: StatusRuntimeException) { throw DataBrokerException(e.message, e) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/JsonWebToken.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/JsonWebToken.kt new file mode 100644 index 00000000..bed3feba --- /dev/null +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/JsonWebToken.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.eclipse.kuksa.authentication + +/** + * A JsonWebToken can be used to authenticate against the DataBroker. For authentication to work the DataBroker must be + * started with authentication enabled first. + * The JsonWebToken is defined by an [authScheme] and [token]. The [authScheme] is set to "Bearer". The [token] should + * contain a valid JsonWebToken. + * + * It will be send to the DataBroker as part of the Header Metadata in the following format: + * + * Headers + * Authorization: [authScheme] [token] + * + */ +data class JsonWebToken( + val token: String, +) { + val authScheme: String + get() = DEFAULT_AUTH_SCHEME + + private companion object { + private const val DEFAULT_AUTH_SCHEME = "Bearer" + } +} diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/VALStubExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/VALStubExtension.kt new file mode 100644 index 00000000..7150f76b --- /dev/null +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/VALStubExtension.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.eclipse.kuksa.authentication + +import com.google.common.net.HttpHeaders +import io.grpc.ClientInterceptor +import io.grpc.Metadata +import io.grpc.stub.MetadataUtils +import org.eclipse.kuksa.proto.v1.VALGrpc.VALBlockingStub +import org.eclipse.kuksa.proto.v1.VALGrpc.VALStub + +internal fun VALBlockingStub.withAuthenticationInterceptor(jsonWebToken: JsonWebToken?): VALBlockingStub { + if (jsonWebToken == null) return this + + val authenticationInterceptor = clientInterceptor(jsonWebToken) + return withInterceptors(authenticationInterceptor) +} + +internal fun VALStub.withAuthenticationInterceptor(jsonWebToken: JsonWebToken?): VALStub { + if (jsonWebToken == null) return this + + val authenticationInterceptor = clientInterceptor(jsonWebToken) + return withInterceptors(authenticationInterceptor) +} + +private fun clientInterceptor(jsonWebToken: JsonWebToken): ClientInterceptor? { + val authorizationHeader = Metadata.Key.of(HttpHeaders.AUTHORIZATION, Metadata.ASCII_STRING_MARSHALLER) + + val metadata = Metadata() + metadata.put(authorizationHeader, "${jsonWebToken.authScheme} ${jsonWebToken.token}") + + return MetadataUtils.newAttachHeadersInterceptor(metadata) +} From 7a40e924a9d66b0621e4e312418ac4233c7e538a Mon Sep 17 00:00:00 2001 From: Andre Weber Date: Wed, 21 Feb 2024 09:46:42 +0100 Subject: [PATCH 2/8] feature(TestApp): Add TestApp Support for Authentication --- .../databroker/JavaDataBrokerEngine.java | 52 +++++++++++++++---- .../databroker/KotlinDataBrokerEngine.kt | 48 +++++++++++++---- .../databroker/model/ConnectionInfo.kt | 4 +- .../view/DataBrokerConnectionView.kt | 26 +++++++++- 4 files changed, 108 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java index a853735e..5b09e82c 100644 --- a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java +++ b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java @@ -19,7 +19,9 @@ package org.eclipse.kuksa.testapp.databroker; +import android.content.ContentResolver; import android.content.Context; +import android.net.Uri; import android.util.Log; import androidx.annotation.NonNull; @@ -31,6 +33,7 @@ import org.eclipse.kuksa.PropertyListener; import org.eclipse.kuksa.TimeoutConfig; import org.eclipse.kuksa.VssSpecificationListener; +import org.eclipse.kuksa.authentication.JsonWebToken; import org.eclipse.kuksa.model.Property; import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse; import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse; @@ -43,6 +46,7 @@ import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -55,6 +59,8 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.TlsChannelCredentials; +import kotlin.io.TextStreamsKt; +import kotlin.text.Charsets; public class JavaDataBrokerEngine implements DataBrokerEngine { private static final String TAG = JavaDataBrokerEngine.class.getSimpleName(); @@ -73,21 +79,28 @@ public void connect( if (connectionInfo.isTlsEnabled()) { connectSecure(context, connectionInfo, callback); } else { - connectInsecure(connectionInfo, callback); + connectInsecure(context, connectionInfo, callback); } } private void connectInsecure( - @NonNull ConnectionInfo connectInfo, + @NonNull Context context, + @NonNull ConnectionInfo connectionInfo, @NonNull CoroutineCallback callback ) { try { ManagedChannel managedChannel = ManagedChannelBuilder - .forAddress(connectInfo.getHost(), connectInfo.getPort()) + .forAddress(connectionInfo.getHost(), connectionInfo.getPort()) .usePlaintext() .build(); - connect(managedChannel, callback); + String jwtUriPath = connectionInfo.getJwtUriPath(); + JsonWebToken jsonWebToken = null; + if (jwtUriPath != null) { + jsonWebToken = loadJsonWebToken(context, jwtUriPath); + } + + connect(managedChannel, jsonWebToken, callback); } catch (IllegalArgumentException e) { callback.onError(e); } @@ -95,10 +108,10 @@ private void connectInsecure( private void connectSecure( @NotNull Context context, - @NotNull ConnectionInfo connectInfo, + @NotNull ConnectionInfo connectionInfo, @NotNull CoroutineCallback callback ) { - Certificate certificate = connectInfo.getCertificate(); + Certificate certificate = connectionInfo.getCertificate(); ChannelCredentials tlsCredentials; try { @@ -116,7 +129,7 @@ private void connectSecure( try { ManagedChannelBuilder channelBuilder = Grpc - .newChannelBuilderForAddress(connectInfo.getHost(), connectInfo.getPort(), tlsCredentials); + .newChannelBuilderForAddress(connectionInfo.getHost(), connectionInfo.getPort(), tlsCredentials); String overrideAuthority = certificate.getOverrideAuthority().trim(); boolean hasOverrideAuthority = !overrideAuthority.isEmpty(); @@ -124,8 +137,14 @@ private void connectSecure( channelBuilder.overrideAuthority(overrideAuthority); } + String jwtUriPath = connectionInfo.getJwtUriPath(); + JsonWebToken jsonWebToken = null; + if (jwtUriPath != null) { + jsonWebToken = loadJsonWebToken(context, jwtUriPath); + } + ManagedChannel managedChannel = channelBuilder.build(); - connect(managedChannel, callback); + connect(managedChannel, jsonWebToken, callback); } catch (IllegalArgumentException e) { callback.onError(e); } @@ -133,9 +152,10 @@ private void connectSecure( private void connect( @NonNull ManagedChannel managedChannel, + @Nullable JsonWebToken jsonWebToken, @NonNull CoroutineCallback callback ) { - DataBrokerConnector connector = new DataBrokerConnector(managedChannel); + DataBrokerConnector connector = new DataBrokerConnector(managedChannel, jsonWebToken); connector.setTimeoutConfig(new TimeoutConfig(TIMEOUT_CONNECTION, TimeUnit.SECONDS)); connector.connect(new CoroutineCallback<>() { @Override @@ -278,4 +298,18 @@ public void unsubscribe(@NonNull Property property, @NonNull PropertyListener pr dataBrokerConnection.unsubscribe(property, propertyListener); } } + + public JsonWebToken loadJsonWebToken(Context context, String uriPath) { + Uri uri = Uri.parse(uriPath); + + ContentResolver contentResolver = context.getContentResolver(); + try (InputStream inputStream = contentResolver.openInputStream(uri)) { + InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charsets.UTF_8); + String token = TextStreamsKt.readText(inputStreamReader); + + return new JsonWebToken(token); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt index 2b08977a..d3903265 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt @@ -20,6 +20,7 @@ package org.eclipse.kuksa.testapp.databroker import android.content.Context +import android.net.Uri import androidx.lifecycle.LifecycleCoroutineScope import io.grpc.ChannelCredentials import io.grpc.Grpc @@ -35,6 +36,7 @@ import org.eclipse.kuksa.DisconnectListener import org.eclipse.kuksa.PropertyListener import org.eclipse.kuksa.TimeoutConfig import org.eclipse.kuksa.VssSpecificationListener +import org.eclipse.kuksa.authentication.JsonWebToken import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse @@ -59,21 +61,26 @@ class KotlinDataBrokerEngine( if (connectionInfo.isTlsEnabled) { connectSecure(context, connectionInfo, callback) } else { - connectInsecure(connectionInfo, callback) + connectInsecure(context, connectionInfo, callback) } } private fun connectInsecure( - connectInfo: ConnectionInfo, + context: Context, + connectionInfo: ConnectionInfo, callback: CoroutineCallback, ) { try { val managedChannel = ManagedChannelBuilder - .forAddress(connectInfo.host, connectInfo.port) + .forAddress(connectionInfo.host, connectionInfo.port) .usePlaintext() .build() - connect(managedChannel, callback) + val jsonWebToken = connectionInfo.jwtUriPath?.let { + loadJsonWebToken(context, it) + } + + connect(managedChannel, jsonWebToken, callback) } catch (e: IllegalArgumentException) { callback.onError(e) } @@ -81,10 +88,10 @@ class KotlinDataBrokerEngine( private fun connectSecure( context: Context, - connectInfo: ConnectionInfo, + connectionInfo: ConnectionInfo, callback: CoroutineCallback, ) { - val certificate = connectInfo.certificate + val certificate = connectionInfo.certificate val tlsCredentials: ChannelCredentials try { @@ -98,8 +105,8 @@ class KotlinDataBrokerEngine( } try { - val host = connectInfo.host.trim() - val port = connectInfo.port + val host = connectionInfo.host.trim() + val port = connectionInfo.port val channelBuilder = Grpc .newChannelBuilderForAddress(host, port, tlsCredentials) @@ -109,15 +116,23 @@ class KotlinDataBrokerEngine( channelBuilder.overrideAuthority(overrideAuthority) } + val jsonWebToken = connectionInfo.jwtUriPath?.let { + loadJsonWebToken(context, it) + } + val managedChannel = channelBuilder.build() - connect(managedChannel, callback) + connect(managedChannel, jsonWebToken, callback) } catch (e: IllegalArgumentException) { callback.onError(e) } } - private fun connect(managedChannel: ManagedChannel, callback: CoroutineCallback) { - val connector = DataBrokerConnector(managedChannel).apply { + private fun connect( + managedChannel: ManagedChannel, + jsonWebToken: JsonWebToken?, + callback: CoroutineCallback, + ) { + val connector = DataBrokerConnector(managedChannel, jsonWebToken).apply { timeoutConfig = TimeoutConfig(TIMEOUT_CONNECTION_SEC) } @@ -207,6 +222,17 @@ class KotlinDataBrokerEngine( dataBrokerConnection?.disconnectListeners?.unregister(listener) } + private fun loadJsonWebToken(context: Context, uriPath: String): JsonWebToken { + val uri = Uri.parse(uriPath) + + val contentResolver = context.contentResolver + val token: String = contentResolver.openInputStream(uri)?.use { + it.reader().readText() + } ?: error("Could not read jwt") + + return JsonWebToken(token) + } + companion object { const val TIMEOUT_CONNECTION_SEC = 5L } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/model/ConnectionInfo.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/model/ConnectionInfo.kt index 1529e0ac..2c4788f7 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/model/ConnectionInfo.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/model/ConnectionInfo.kt @@ -28,8 +28,10 @@ import org.eclipse.kuksa.testapp.serialization.JsonSerializer data class ConnectionInfo( val host: String = "localhost", val port: Int = 55556, - val certificate: Certificate = Certificate.DEFAULT, val isTlsEnabled: Boolean = false, + val certificate: Certificate = Certificate.DEFAULT, + val isAuthenticationEnabled: Boolean = false, + val jwtUriPath: String? = null, ) object ConnectionInfoSerializer : JsonSerializer(ConnectionInfo.serializer()) { diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerConnectionView.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerConnectionView.kt index 04955eb6..50e479e9 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerConnectionView.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerConnectionView.kt @@ -19,6 +19,7 @@ package org.eclipse.kuksa.testapp.databroker.view +import android.net.Uri import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.Arrangement @@ -186,9 +187,32 @@ fun DataBrokerConnection(viewModel: ConnectionViewModel) { }, ) } + } + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(start = DefaultEdgePadding, end = DefaultEdgePadding), + ) { + Text(text = "Authentication:") + Checkbox(checked = connectionInfo.isAuthenticationEnabled, onCheckedChange = { isChecked -> + val newConnectionInfo = connectionInfo.copy(isAuthenticationEnabled = isChecked) + viewModel.updateConnectionInfo(newConnectionInfo) + }) + } - Spacer(modifier = Modifier.padding(top = DefaultElementPadding)) + if (connectionInfo.isAuthenticationEnabled) { + val uri = Uri.parse(connectionInfo.jwtUriPath ?: "") + val fileName = uri.fetchFileName(context) ?: "Select JWT..." + + FileSelectorSettingView( + label = "JWT", + value = fileName, + modifier = Modifier.padding(start = DefaultEdgePadding, end = DefaultEdgePadding), + ) { + val newConnectionInfo = connectionInfo.copy(jwtUriPath = it.toString()) + viewModel.updateConnectionInfo(newConnectionInfo) + } } + Spacer(modifier = Modifier.padding(top = DefaultElementPadding)) } } Row( From b449410a03a58271224ff78061b72e207157c87a Mon Sep 17 00:00:00 2001 From: Andre Weber Date: Wed, 21 Feb 2024 12:18:59 +0100 Subject: [PATCH 3/8] test: Add Tests for Authentication --- .run/kuksa-sdk_IntegrationSecureTests.run.xml | 23 --- .run/kuksa-sdk_IntegrationTests.run.xml | 3 +- .../eclipse/kuksa/DataBrokerConnectionTest.kt | 3 +- .../DataBrokerConnectorAuthenticationTest.kt | 175 ++++++++++++++++++ .../kuksa/DataBrokerConnectorSecureTest.kt | 7 +- .../eclipse/kuksa/DataBrokerConnectorTest.kt | 3 +- .../kuksa/DataBrokerTransporterTest.kt | 3 +- .../databroker/DataBrokerConnectorProvider.kt | 24 ++- .../subscription/DataBrokerSubscriberTest.kt | 3 +- .../test/resources/actuate-provide-all.token | 1 + .../src/test/resources/provide-all.token | 1 + kuksa-sdk/src/test/resources/read-all.token | 1 + .../java/org/eclipse/kuksa/test/kotest/Tag.kt | 5 +- 13 files changed, 220 insertions(+), 32 deletions(-) delete mode 100644 .run/kuksa-sdk_IntegrationSecureTests.run.xml create mode 100644 kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorAuthenticationTest.kt create mode 100644 kuksa-sdk/src/test/resources/actuate-provide-all.token create mode 100644 kuksa-sdk/src/test/resources/provide-all.token create mode 100644 kuksa-sdk/src/test/resources/read-all.token diff --git a/.run/kuksa-sdk_IntegrationSecureTests.run.xml b/.run/kuksa-sdk_IntegrationSecureTests.run.xml deleted file mode 100644 index 3be2c124..00000000 --- a/.run/kuksa-sdk_IntegrationSecureTests.run.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - true - true - false - - - \ No newline at end of file diff --git a/.run/kuksa-sdk_IntegrationTests.run.xml b/.run/kuksa-sdk_IntegrationTests.run.xml index a0ace44d..12bc49be 100644 --- a/.run/kuksa-sdk_IntegrationTests.run.xml +++ b/.run/kuksa-sdk_IntegrationTests.run.xml @@ -13,11 +13,12 @@ -