diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.kt index c847e8c0c..d1491b20f 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.kt +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.kt @@ -23,7 +23,7 @@ import java.net.URI import java.nio.file.Path interface AcmeClient { - fun getChallengeAuthorization(challenge: String): String + fun getChallengeAuthorization(challenge: String): String? fun renewCertificate( targetDirectory: Path, diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.kt index 8ca532fb4..b1ebfaa78 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.kt +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.kt @@ -21,4 +21,4 @@ package de.fhg.aisec.ids.api.acme import com.fasterxml.jackson.annotation.JsonProperty -class AcmeTermsOfService(val tos: String, @get:JsonProperty(value = "isUri") val isUri: Boolean, val error: String) +class AcmeTermsOfService(val tos: String?, @get:JsonProperty(value = "isUri") val isUri: Boolean?, val error: String?) diff --git a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.java b/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.java deleted file mode 100644 index 2aca71af1..000000000 --- a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.java +++ /dev/null @@ -1,224 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * 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. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.cm.impl.trustx; - -import de.fhg.aisec.ids.comm.unixsocket.ChangeRequest; -import jnr.enxio.channels.NativeSelectorProvider; -import jnr.unixsocket.UnixServerSocketChannel; -import jnr.unixsocket.UnixSocketAddress; -import jnr.unixsocket.UnixSocketChannel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.util.*; - -public class TrustXMock implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger(TrustXMock.class); - private UnixServerSocketChannel channel; - private String socket; - - // The selector we'll be monitoring - private final Selector selector; - - // The buffer into which we'll read data when it's available - private final ByteBuffer readBuffer = ByteBuffer.allocate(1024 * 1024); - - // A list of PendingChange instances - private final List pendingChanges = new LinkedList<>(); - - // Maps a UnixSocketChannel to a list of ByteBuffer instances - private final Map> pendingData = new HashMap<>(); - - private final TrustXMockHandler handler; - - // constructor setting another socket address - public TrustXMock(String socket, TrustXMockHandler handler) throws IOException { - this.setSocket(socket); - this.selector = this.initSelector(); - this.handler = handler; - } - - // send a protobuf message to the unix socket - public void send(UnixSocketChannel socket, byte[] data) { - synchronized (this.pendingChanges) { - this.pendingChanges.add( - new ChangeRequest(socket, ChangeRequest.CHANGEOPS, SelectionKey.OP_WRITE)); - // And queue the data we want written - synchronized (this.pendingData) { - List queue = this.pendingData.computeIfAbsent(socket, k -> new ArrayList<>()); - queue.add(ByteBuffer.wrap(data)); - } - // Finally, wake up our selecting thread so it can make the required changes - this.selector.wakeup(); - } - } - - // thread run method - @Override - public void run() { - while (!Thread.interrupted()) { - try { - // Process any pending changes - synchronized (this.pendingChanges) { - for (ChangeRequest change : this.pendingChanges) { - if (change.type == ChangeRequest.CHANGEOPS) { - SelectionKey key = change.channel.keyFor(this.selector); - key.interestOps(change.ops); - } - } - this.pendingChanges.clear(); - } - - // Wait for an event on one of the registered channels - this.selector.select(); - - // Iterate over the set of keys for which events are available - Iterator selectedKeys = this.selector.selectedKeys().iterator(); - while (selectedKeys.hasNext()) { - SelectionKey key = selectedKeys.next(); - selectedKeys.remove(); - if (!key.isValid()) { - continue; - } - // Check what event is available and deal with it - if (key.isAcceptable()) { - this.accept(key); - } else if (key.isReadable()) { - this.read(key); - } else if (key.isWritable()) { - this.write(key); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - @SuppressWarnings("unused") - private void accept(SelectionKey key) throws IOException { - // Accept the connection and make it non-blocking - UnixSocketChannel client = channel.accept(); - client.configureBlocking(false); - - // Register the new SocketChannel with our Selector, indicating - // we'd like to be notified when there's data waiting to be read - client.register(this.selector, SelectionKey.OP_READ); - } - - // read send some data from the unix socket - private void read(SelectionKey key) throws IOException { - UnixSocketChannel channel = this.getChannel(key); - - // Clear out our read buffer so it's ready for new data - this.readBuffer.clear(); - - // Attempt to read off the channel - int numRead; - try { - numRead = channel.read(this.readBuffer); - } catch (IOException e) { - // The remote forcibly closed the connection, cancel the selection key and close the channel. - key.cancel(); - channel.close(); - return; - } - LOG.debug("bytes read: " + numRead); - if (numRead == -1) { - // Remote entity shut the socket down cleanly. Do the same from our end and cancel the - // channel. - key.channel().close(); - key.cancel(); - return; - } - handler.handleResponse(this, channel, this.readBuffer.array(), numRead); - } - - private void write(SelectionKey key) throws IOException { - final UnixSocketChannel channel = this.getChannel(key); - - synchronized (this.pendingData) { - List queue = this.pendingData.get(channel); - - // Write until there's not more data - while (!queue.isEmpty()) { - ByteBuffer buf = queue.get(0); - channel.write(buf); - if (buf.remaining() > 0) { - // ... or the socket's buffer fills up - break; - } - queue.remove(0); - } - if (queue.isEmpty()) { - // We wrote away all data, so we're no longer interested in writing on this socket. Switch - // back to waiting for data. - key.interestOps(SelectionKey.OP_READ); - } - } - } - - // initialize the selector - private Selector initSelector() throws IOException { - Selector socketSelector = NativeSelectorProvider.getInstance().openSelector(); - - File socketFile = new File(getSocket()); - //noinspection ResultOfMethodCallIgnored - socketFile.delete(); - socketFile.deleteOnExit(); - - UnixSocketAddress address = new UnixSocketAddress(socketFile.getAbsoluteFile()); - this.channel = UnixServerSocketChannel.open(); - this.channel.configureBlocking(false); - this.channel.socket().bind(address); - - channel.register(socketSelector, SelectionKey.OP_ACCEPT); - - return socketSelector; - } - - // get the channel - private UnixSocketChannel getChannel(SelectionKey k) { - return (UnixSocketChannel) k.channel(); - } - - public String getSocket() { - return socket; - } - - public void setSocket(String socket) { - this.socket = socket; - } - - public static void main(String[] args) { - try { - TrustXMockHandler handler = new TrustXMockHandler(); - new Thread(handler).start(); - new Thread(new TrustXMock("src/test/socket/trustme.sock", handler)).start(); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.java b/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.java deleted file mode 100644 index 8dec14317..000000000 --- a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * 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. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.cm.impl.trustx; - -import jnr.unixsocket.UnixSocketChannel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.LinkedList; -import java.util.List; - -public class TrustXMockHandler implements Runnable { - private final List queue = new LinkedList<>(); - - @Override - public void run() { - ServerDataEvent dataEvent; - - //noinspection InfiniteLoopStatement - while (true) { - // Wait for data to become available - synchronized (queue) { - while (queue.isEmpty()) { - try { - queue.wait(); - } catch (InterruptedException ignored) { - } - } - dataEvent = queue.remove(0); - } - - // Print - System.out.println(new String(dataEvent.data)); - dataEvent.server.send(dataEvent.socket, dataEvent.data); - } - } - - public void handleResponse(TrustXMock server, UnixSocketChannel socket, byte[] data, int count) { - byte[] dataCopy = new byte[count]; - System.arraycopy(data, 0, dataCopy, 0, count); - synchronized (queue) { - queue.add(new ServerDataEvent(server, socket, dataCopy)); - queue.notify(); - } - } -} diff --git a/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.kt b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.kt index 4999d21cd..51ae8bc49 100644 --- a/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.kt +++ b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.kt @@ -63,12 +63,12 @@ class DockerCmIT { val oContainerID = d.pullImage(app) // We expect a new container to be created - Assert.assertTrue(oContainerID.isPresent) - Assert.assertNotEquals("", oContainerID.get()) - wipes.add(oContainerID.get()) + Assert.assertNotNull(oContainerID) + Assert.assertNotEquals("", oContainerID) + wipes.add(oContainerID!!) // we expect the container to be in list() - val container = d.list(false).firstOrNull { it.id == oContainerID.get() } + val container = d.list(false).firstOrNull { it.id == oContainerID } Assert.assertNotNull(container) Assert.assertEquals(ContainerStatus.CREATED, container?.status) } @@ -98,8 +98,8 @@ class DockerCmIT { val oContainerID = d.pullImage(app) // We expect a new container to be created - Assert.assertTrue(oContainerID.isPresent) - val containerID = oContainerID.get() + Assert.assertNotNull(oContainerID) + val containerID = oContainerID!! wipes.add(containerID) Assert.assertNotNull(containerID) diff --git a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/ServerDataEvent.java b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/ServerDataEvent.kt similarity index 68% rename from ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/ServerDataEvent.java rename to ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/ServerDataEvent.kt index 4b30d45a8..e143f7ee6 100644 --- a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/ServerDataEvent.java +++ b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/ServerDataEvent.kt @@ -17,18 +17,8 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.cm.impl.trustx; +package de.fhg.aisec.ids.cm.impl.trustx -import jnr.unixsocket.UnixSocketChannel; +import jnr.unixsocket.UnixSocketChannel -class ServerDataEvent { - public TrustXMock server; - public UnixSocketChannel socket; - public byte[] data; - - public ServerDataEvent(TrustXMock server, UnixSocketChannel socket, byte[] data) { - this.server = server; - this.socket = socket; - this.data = data; - } -} +internal class ServerDataEvent(var server: TrustXMock, var socket: UnixSocketChannel, var data: ByteArray) diff --git a/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.kt b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.kt new file mode 100644 index 000000000..2ee9923ce --- /dev/null +++ b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.kt @@ -0,0 +1,208 @@ +/*- + * ========================LICENSE_START================================= + * ids-container-manager + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * 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. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.cm.impl.trustx + +import de.fhg.aisec.ids.comm.unixsocket.ChangeRequest +import jnr.enxio.channels.NativeSelectorProvider +import jnr.unixsocket.UnixServerSocketChannel +import jnr.unixsocket.UnixSocketAddress +import jnr.unixsocket.UnixSocketChannel +import org.slf4j.LoggerFactory +import java.io.File +import java.io.IOException +import java.nio.ByteBuffer +import java.nio.channels.SelectionKey +import java.nio.channels.Selector +import java.util.LinkedList + +class TrustXMock(private var socket: String, private var handler: TrustXMockHandler) : Runnable { + private var channel: UnixServerSocketChannel? = null + + // The selector we'll be monitoring + private val selector: Selector = initSelector() + + // The buffer into which we'll read data when it's available + private val readBuffer = ByteBuffer.allocate(1024 * 1024) + + // A list of PendingChange instances + private val pendingChanges: MutableList = LinkedList() + + // Maps a UnixSocketChannel to a list of ByteBuffer instances + private val pendingData: MutableMap> = HashMap() + + // send a protobuf message to the unix socket + fun send(socket: UnixSocketChannel?, data: ByteArray?) { + synchronized(pendingChanges) { + pendingChanges.add( + ChangeRequest(socket!!, ChangeRequest.CHANGEOPS, SelectionKey.OP_WRITE) + ) + // And queue the data we want written + synchronized(pendingData) { + val queue = pendingData.computeIfAbsent(socket) { ArrayList() } + queue.add(ByteBuffer.wrap(data)) + } + // Finally, wake up our selecting thread so it can make the required changes + selector.wakeup() + } + } + + // thread run method + override fun run() { + while (!Thread.interrupted()) { + try { + // Process any pending changes + synchronized(pendingChanges) { + for (change in pendingChanges) { + if (change.type == ChangeRequest.CHANGEOPS) { + val key = change.channel.keyFor(selector) + key.interestOps(change.ops) + } + } + pendingChanges.clear() + } + + // Wait for an event on one of the registered channels + selector.select() + + // Iterate over the set of keys for which events are available + val selectedKeys = selector.selectedKeys().iterator() + while (selectedKeys.hasNext()) { + val key = selectedKeys.next() + selectedKeys.remove() + if (!key.isValid) { + continue + } + // Check what event is available and deal with it + when { + key.isAcceptable -> { + accept() + } + key.isReadable -> { + read(key) + } + key.isWritable -> { + write(key) + } + } + } + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + @Throws(IOException::class) + private fun accept() { + // Accept the connection and make it non-blocking + val client = channel!!.accept() + client.configureBlocking(false) + + // Register the new SocketChannel with our Selector, indicating + // we'd like to be notified when there's data waiting to be read + client.register(selector, SelectionKey.OP_READ) + } + + // read send some data from the unix socket + @Throws(IOException::class) + private fun read(key: SelectionKey) { + val channel = getChannel(key) + + // Clear out our read buffer so it's ready for new data + readBuffer.clear() + + // Attempt to read off the channel + val numRead: Int = try { + channel.read(readBuffer) + } catch (e: IOException) { + // The remote forcibly closed the connection, cancel the selection key and close the channel. + key.cancel() + channel.close() + return + } + LOG.debug("bytes read: $numRead") + if (numRead == -1) { + // Remote entity shut the socket down cleanly. Do the same from our end and cancel the + // channel. + key.channel().close() + key.cancel() + return + } + handler.handleResponse(this, channel, readBuffer.array(), numRead) + } + + @Throws(IOException::class) + private fun write(key: SelectionKey) { + val channel = getChannel(key) + synchronized(pendingData) { + val queue: MutableList = pendingData[channel]!! + + // Write until there's not more data + while (queue.isNotEmpty()) { + val buf = queue[0] + channel.write(buf) + if (buf.remaining() > 0) { + // ... or the socket's buffer fills up + break + } + queue.removeAt(0) + } + if (queue.isEmpty()) { + // We wrote away all data, so we're no longer interested in writing on this socket. Switch + // back to waiting for data. + key.interestOps(SelectionKey.OP_READ) + } + } + } + + // initialize the selector + @Throws(IOException::class) + private fun initSelector(): Selector { + val socketSelector: Selector = NativeSelectorProvider.getInstance().openSelector() + val socketFile = File(socket) + socketFile.delete() + socketFile.deleteOnExit() + val address = UnixSocketAddress(socketFile.absoluteFile) + channel = UnixServerSocketChannel.open().apply { + configureBlocking(false) + socket().bind(address) + register(socketSelector, SelectionKey.OP_ACCEPT) + } + return socketSelector + } + + // get the channel + private fun getChannel(k: SelectionKey): UnixSocketChannel { + return k.channel() as UnixSocketChannel + } + + companion object { + private val LOG = LoggerFactory.getLogger(TrustXMock::class.java) + @JvmStatic + fun main(args: Array) { + try { + val handler = TrustXMockHandler() + Thread(handler).start() + Thread(TrustXMock("src/test/socket/trustme.sock", handler)).start() + } catch (e: IOException) { + e.printStackTrace() + } + } + } +} diff --git a/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.kt b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.kt new file mode 100644 index 000000000..1c0e64382 --- /dev/null +++ b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.kt @@ -0,0 +1,60 @@ +/*- + * ========================LICENSE_START================================= + * ids-container-manager + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * 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. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.cm.impl.trustx + +import jnr.unixsocket.UnixSocketChannel +import java.util.LinkedList +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock + +class TrustXMockHandler : Runnable { + private val lock = ReentrantLock() + private val condition = lock.newCondition() + private val queue: MutableList = LinkedList() + + override fun run() { + var dataEvent: ServerDataEvent + while (true) { + // Wait for data to become available + lock.withLock { + while (queue.isEmpty()) { + try { + condition.await() + } catch (ignored: InterruptedException) { + } + } + dataEvent = queue.removeAt(0) + } + + // Print + println(String(dataEvent.data)) + dataEvent.server.send(dataEvent.socket, dataEvent.data) + } + } + + fun handleResponse(server: TrustXMock, socket: UnixSocketChannel, data: ByteArray, count: Int) { + val dataCopy = ByteArray(count) + System.arraycopy(data, 0, dataCopy, 0, count) + lock.withLock { + queue.add(ServerDataEvent(server, socket, dataCopy)) + condition.signal() + } + } +} diff --git a/ids-dataflow-control/src/test/kotlin/de/fhg/aisec/ids/dataflowcontrol/LuconEngineTest.kt b/ids-dataflow-control/src/test/kotlin/de/fhg/aisec/ids/dataflowcontrol/LuconEngineTest.kt index 24215550d..d2025483a 100644 --- a/ids-dataflow-control/src/test/kotlin/de/fhg/aisec/ids/dataflowcontrol/LuconEngineTest.kt +++ b/ids-dataflow-control/src/test/kotlin/de/fhg/aisec/ids/dataflowcontrol/LuconEngineTest.kt @@ -134,8 +134,8 @@ class LuconEngineTest { pdp.loadPolicy(EXAMPLE_POLICY) // Simple source and dest nodes - val source = ServiceNode("seda:test_source", null, null) - val dest = ServiceNode("hdfs://some_url", null, null) + val source = ServiceNode("seda:test_source") + val dest = ServiceNode("hdfs://some_url") val dec = pdp.requestDecision(DecisionRequest(source, dest, setOf("private"), null)) Assert.assertEquals(PolicyDecision.Decision.ALLOW, dec.decision) @@ -156,8 +156,8 @@ class LuconEngineTest { pdp.loadPolicy(EXTENDED_LABELS_POLICY) // Simple source and dest nodes - val source = ServiceNode("seda:test_source", null, null) - val dest = ServiceNode("ahc://some_url", null, null) + val source = ServiceNode("seda:test_source") + val dest = ServiceNode("ahc://some_url") val dec = pdp.requestDecision(DecisionRequest(source, dest, setOf("purpose(green)"), null)) Assert.assertEquals(PolicyDecision.Decision.ALLOW, dec.decision) @@ -192,7 +192,7 @@ class LuconEngineTest { val pdp = PolicyDecisionPoint() pdp.loadPolicies() pdp.loadPolicy(EXAMPLE_POLICY) - val node = ServiceNode("paho:tcp://broker.hivemq.com:1883/blablubb", null, null) + val node = ServiceNode("paho:tcp://broker.hivemq.com:1883/blablubb") val trans = pdp.requestTranformations(node) Assert.assertNotNull(trans) Assert.assertNotNull(trans.labelsToAdd) @@ -208,7 +208,7 @@ class LuconEngineTest { val pdp = PolicyDecisionPoint() pdp.loadPolicies() pdp.loadPolicy(EXAMPLE_POLICY) - val node = ServiceNode("someendpointwhichisnotmatchedbypolicy", null, null) + val node = ServiceNode("someendpointwhichisnotmatchedbypolicy") val trans = pdp.requestTranformations(node) Assert.assertNotNull(trans) Assert.assertNotNull(trans.labelsToAdd) @@ -281,8 +281,8 @@ class LuconEngineTest { val loadTime = stop - start // Simple source and dest nodes - val source = ServiceNode("seda:test_source", null, null) - val dest = ServiceNode("hdfs://some_url", null, null) + val source = ServiceNode("seda:test_source") + val dest = ServiceNode("hdfs://some_url") start = System.nanoTime() val dec = pdp.requestDecision(DecisionRequest(source, dest, emptySet(), null)) stop = System.nanoTime() @@ -309,8 +309,8 @@ class LuconEngineTest { val loadTime = stop - start // Simple source and dest nodes - val source = ServiceNode("seda:test_source", null, null) - val dest = ServiceNode("hdfs://some_url", null, null) + val source = ServiceNode("seda:test_source") + val dest = ServiceNode("hdfs://some_url") start = System.nanoTime() val dec = pdp.requestDecision(DecisionRequest(source, dest, emptySet(), null)) stop = System.nanoTime() @@ -334,8 +334,8 @@ class LuconEngineTest { pdp.loadPolicy(theory) // Simple source and dest nodes - val source = ServiceNode("seda:test_source", null, null) - val dest = ServiceNode("hdfs://some_url", null, null) + val source = ServiceNode("seda:test_source") + val dest = ServiceNode("hdfs://some_url") System.gc() System.gc() System.gc() // Empty level 1- & 2-LRUs. @@ -373,8 +373,8 @@ class LuconEngineTest { pdp.loadPolicy(theory) // Simple source and dest nodes - val source = ServiceNode("seda:test_source", null, null) - val dest = ServiceNode("hdfs://some_url", null, null) + val source = ServiceNode("seda:test_source") + val dest = ServiceNode("hdfs://some_url") System.gc() System.gc() System.gc() // Empty level 1- & 2-LRUs. @@ -415,10 +415,9 @@ class LuconEngineTest { Assert.assertEquals("testRulePrioTwo", ruleTwo) // FALL-THROUGH: Test fall-through decision (no msg label matches) - var from = ServiceNode("IAmMatchedByRuleThreeOnly", null, null) - var to = ServiceNode("hdfs://IAmMatchedByBothRules", null, null) - var envCtx: Map = HashMap() - var req = DecisionRequest(from, to, emptySet(), envCtx) + var from = ServiceNode("IAmMatchedByRuleThreeOnly") + var to = ServiceNode("hdfs://IAmMatchedByBothRules") + var req = DecisionRequest(from, to, emptySet(), emptyMap()) var dec = pdp.requestDecision(req) Assert.assertNotNull(dec) var d = dec.decision @@ -427,10 +426,9 @@ class LuconEngineTest { // FALL-THROUGH: presence of a label "public" (w/o any specific value) does not yet trigger // testRulePrioTwo, because label "filtered" is required in addition. - from = ServiceNode("IAmMatchedByRuleThreeOnly", null, null) - to = ServiceNode("hdfs://IAmMatchedByBothRules", null, null) - envCtx = HashMap() - req = DecisionRequest(from, to, setOf("public"), envCtx) + from = ServiceNode("IAmMatchedByRuleThreeOnly") + to = ServiceNode("hdfs://IAmMatchedByBothRules") + req = DecisionRequest(from, to, setOf("public"), emptyMap()) dec = pdp.requestDecision(req) Assert.assertNotNull(dec) d = dec.decision @@ -440,10 +438,9 @@ class LuconEngineTest { // testRulePrioTwo: now we have labels "public" AND "filtered" set, which makes // testRulePrioTwo // match - from = ServiceNode("IAmMatchedByRuleThreeOnly", null, null) - to = ServiceNode("hdfs://IAmMatchedByBothRules", null, null) - envCtx = HashMap() - req = DecisionRequest(from, to, setOf("public", "filtered"), envCtx) + from = ServiceNode("IAmMatchedByRuleThreeOnly") + to = ServiceNode("hdfs://IAmMatchedByBothRules") + req = DecisionRequest(from, to, setOf("public", "filtered"), emptyMap()) dec = pdp.requestDecision(req) Assert.assertNotNull(dec) d = dec.decision @@ -453,10 +450,9 @@ class LuconEngineTest { // testRulePrioTwo: "public" AND "filtered" makes testRulePrioTwo match. Additional labels // do // not harm - from = ServiceNode("IAmMatchedByRuleThreeOnly", null, null) - to = ServiceNode("hdfs://IAmMatchedByBothRules", null, null) - envCtx = HashMap() - req = DecisionRequest(from, to, setOf("public", "unusedlabel"), envCtx) + from = ServiceNode("IAmMatchedByRuleThreeOnly") + to = ServiceNode("hdfs://IAmMatchedByBothRules") + req = DecisionRequest(from, to, setOf("public", "unusedlabel"), emptyMap()) dec = pdp.requestDecision(req) Assert.assertNotNull(dec) d = dec.decision @@ -465,10 +461,9 @@ class LuconEngineTest { // testRulePrioTwo: labels "public", "filtered", "private" will trigger testRulePrioOne and // testRulePrioTwo. Rule with higher prio wins. - from = ServiceNode("IAmMatchedByRuleThreeOnly", null, null) - to = ServiceNode("hdfs://IAmMatchedByBothRules", null, null) - envCtx = HashMap() - req = DecisionRequest(from, to, setOf("public", "unusedlabel", "private"), envCtx) + from = ServiceNode("IAmMatchedByRuleThreeOnly") + to = ServiceNode("hdfs://IAmMatchedByBothRules") + req = DecisionRequest(from, to, setOf("public", "unusedlabel", "private"), emptyMap()) dec = pdp.requestDecision(req) Assert.assertNotNull(dec) d = dec.decision diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index 4dd808c2f..c9ec15293 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -70,6 +70,7 @@ dependencies { implementation(project(":ids-api")) implementation("org.springframework.boot:spring-boot-starter-jersey") implementation("org.springframework.security", "spring-security-crypto") + implementation("org.bouncycastle", "bcprov-jdk15on", libraryVersions["bouncyCastle"]) implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) implementation("org.apache.camel", "camel-core", libraryVersions["camel"]) implementation("org.apache.cxf", "cxf-rt-rs-extension-providers", libraryVersions["cxf"]) diff --git a/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.kt b/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.kt index 46ecc9107..11600e195 100644 --- a/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.kt +++ b/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.kt @@ -54,7 +54,7 @@ class PortainerCompatibilityIT { 200, 201 -> { val br = BufferedReader(InputStreamReader(c.inputStream)) val sb = StringBuilder() - var line: String + var line: String? while (br.readLine().also { line = it } != null) { sb.append( """ diff --git a/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/RestApiTests.kt b/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/RestApiTests.kt index 912923f1f..b5eef2792 100644 --- a/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/RestApiTests.kt +++ b/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/RestApiTests.kt @@ -45,14 +45,14 @@ import javax.ws.rs.core.Response import kotlin.String class RestApiTests : Assert() { - private fun newClient(vararg token: String): WebClient { + private fun newClient(token: String?): WebClient { // Client uses Jackson for JSON mapping val jackson = JacksonJsonProvider() jackson.setMapper(ObjectMapper()) val client = WebClient.create(ENDPOINT_ADDRESS, listOf(jackson)) WebClient.getConfig(client).requestContext[LocalConduit.DIRECT_DISPATCH] = true - if (token.isNotEmpty()) { - client.header("Authorization", "Bearer: " + token[0]) + token?.let { + client.header("Authorization", "Bearer: $it") } return client } @@ -168,19 +168,18 @@ class RestApiTests : Assert() { } // Access a protected endpoint - @get:Test - val metrics: Unit - get() { - val token = login() - - // Access a protected endpoint - val c = newClient(token!!) - c.accept(MediaType.APPLICATION_JSON) - c.path("/metric/get") - val metrics: Map = - c.get(object : GenericType>() {}) - Assume.assumeFalse(metrics.isEmpty()) - } + @Test + fun getMetricsTest() { + val token = login() + + // Access a protected endpoint + val c = newClient(token!!) + c.accept(MediaType.APPLICATION_JSON) + c.path("/metric/get") + val metrics: Map = + c.get(object : GenericType>() {}) + Assume.assumeFalse(metrics.isEmpty()) + } /** * Retrieves a fresh JWT from server. @@ -188,7 +187,7 @@ class RestApiTests : Assert() { * @return The generated authentication token */ private fun login(): String? { - val c = newClient() + val c = newClient(null) c.path("/user/login") c.accept(MediaType.APPLICATION_JSON) c.header("Content-type", MediaType.APPLICATION_JSON) @@ -204,7 +203,7 @@ class RestApiTests : Assert() { companion object { private const val ENDPOINT_ADDRESS = "local://testserver" - private var server: Server? = null + private lateinit var server: Server private val settings = Mockito.mock( Settings::class.java ) @@ -214,6 +213,7 @@ class RestApiTests : Assert() { fun initialize() { val connectorConfig = ConnectorConfig() Mockito.`when`(settings.connectorConfig).thenReturn(connectorConfig) + Mockito.`when`(settings.isUserStoreEmpty()).thenReturn(true) startServer() } @@ -234,7 +234,7 @@ class RestApiTests : Assert() { sf.providers = providers sf.setResourceProvider(CertApi::class.java, SingletonResourceProvider(CertApi(settings), true)) sf.setResourceProvider(MetricAPI::class.java, SingletonResourceProvider(MetricAPI(), true)) - sf.setResourceProvider(UserApi::class.java, SingletonResourceProvider(UserApi(), true)) + sf.setResourceProvider(UserApi::class.java, SingletonResourceProvider(UserApi(settings), true)) sf.address = ENDPOINT_ADDRESS server = sf.create() } @@ -242,7 +242,7 @@ class RestApiTests : Assert() { @AfterClass @JvmStatic fun destroy() { - server?.run { + server.run { stop() destroy() } diff --git a/libraryVersions.yaml b/libraryVersions.yaml index b67da4f6e..f2d8f5921 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -98,4 +98,5 @@ awaitility: "3.1.6" servicemixHamcrest: "1.3_1" javaxAnnotation: "1.3.2" -springBoot: "2.4.5" \ No newline at end of file +springBoot: "2.4.5" +bouncyCastle: "1.68" \ No newline at end of file