mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-16 01:12:05 +01:00
Some more refactoring and test fixing
This commit is contained in:
parent
73f0976857
commit
7ee0a41a6a
37 changed files with 386 additions and 397 deletions
|
@ -7,7 +7,7 @@ package org.pgpainless.wot.cli.subcommands
|
|||
import org.pgpainless.wot.api.AuthenticateAPI
|
||||
import org.pgpainless.wot.cli.WotCLI
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
import org.pgpainless.wot.network.Path
|
||||
import org.pgpainless.wot.query.Path
|
||||
import picocli.CommandLine
|
||||
import picocli.CommandLine.Command
|
||||
import picocli.CommandLine.Parameters
|
||||
|
|
|
@ -3,6 +3,8 @@ package org.pgpainless.wot.cli.subcommands
|
|||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.wot.api.AuthenticateAPI
|
||||
import org.pgpainless.wot.network.*
|
||||
import org.pgpainless.wot.query.Path
|
||||
import org.pgpainless.wot.query.Paths
|
||||
import java.text.SimpleDateFormat
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -29,7 +31,7 @@ class AuthenticateCmdTest {
|
|||
Pair("Justus Winter <justus@sequoia-pgp.org>", RevocationState.notRevoked())
|
||||
)
|
||||
)
|
||||
val edge = Edge(
|
||||
val edgeComponent = EdgeComponent(
|
||||
neal,
|
||||
justus,
|
||||
"Justus Winter <justus@sequoia-pgp.org>",
|
||||
|
@ -39,7 +41,7 @@ class AuthenticateCmdTest {
|
|||
120,
|
||||
Depth.limited(0),
|
||||
RegexSet.wildcard())
|
||||
paths.add(Path(neal, mutableListOf(edge), Depth.auto(0)), 120)
|
||||
paths.add(Path(neal, mutableListOf(edgeComponent), Depth.auto(0)), 120)
|
||||
val testResult = AuthenticateAPI.Result(
|
||||
Fingerprint("CBCD8F030588653EEDD7E2659B7DD433F254904A"),
|
||||
"Justus Winter <justus@sequoia-pgp.org>",
|
||||
|
|
|
@ -158,7 +158,7 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) {
|
|||
processDelegation(targetPrimaryKey, target, delegation)
|
||||
}
|
||||
|
||||
// Edge Signatures by X on Y over user-ID U
|
||||
// EdgeComponent Signatures by X on Y over user-ID U
|
||||
val userIds = targetPrimaryKey.userIDs
|
||||
while (userIds.hasNext()) {
|
||||
val userId = userIds.next()
|
||||
|
|
|
@ -7,7 +7,7 @@ package org.pgpainless.wot.util
|
|||
import org.bouncycastle.openpgp.PGPSignature
|
||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
|
||||
import org.pgpainless.wot.network.Node
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.EdgeComponent
|
||||
import org.pgpainless.wot.network.Depth
|
||||
import org.pgpainless.wot.network.RegexSet
|
||||
import org.pgpainless.wot.network.RegexSet.Companion.fromExpressionList
|
||||
|
@ -18,7 +18,7 @@ class CertificationFactory {
|
|||
@JvmStatic
|
||||
fun fromDelegation(issuer: Node,
|
||||
target: Node,
|
||||
signature: PGPSignature): Edge {
|
||||
signature: PGPSignature): EdgeComponent {
|
||||
return fromSignature(issuer, target, null, signature)
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ class CertificationFactory {
|
|||
fun fromCertification(issuer: Node,
|
||||
target: Node,
|
||||
targetUserId: String,
|
||||
signature: PGPSignature): Edge {
|
||||
signature: PGPSignature): EdgeComponent {
|
||||
return fromSignature(issuer, target, targetUserId, signature)
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,8 @@ class CertificationFactory {
|
|||
fun fromSignature(issuer: Node,
|
||||
target: Node,
|
||||
targetUserId: String?,
|
||||
signature: PGPSignature): Edge {
|
||||
return Edge(
|
||||
signature: PGPSignature): EdgeComponent {
|
||||
return EdgeComponent(
|
||||
issuer,
|
||||
target,
|
||||
targetUserId,
|
||||
|
|
|
@ -7,7 +7,7 @@ package org.pgpainless.wot
|
|||
import org.bouncycastle.openpgp.PGPPublicKeyRing
|
||||
|
||||
import org.pgpainless.key.OpenPgpFingerprint
|
||||
import org.pgpainless.wot.network.EdgeSet
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
import org.pgpainless.wot.network.Network
|
||||
import org.pgpainless.wot.testfixtures.TestCertificateStores
|
||||
|
@ -55,7 +55,7 @@ class WebOfTrustTest {
|
|||
}
|
||||
}
|
||||
|
||||
val fooBankCaEdges = network.edgeSet[fooBankCa]!!
|
||||
val fooBankCaEdges = network.edges[fooBankCa]!!
|
||||
assertEquals(2, fooBankCaEdges.size)
|
||||
|
||||
val fbc2fbe = getEdgeFromTo(network, fooBankCa, fooBankEmployee)
|
||||
|
@ -80,8 +80,8 @@ class WebOfTrustTest {
|
|||
val network = WebOfTrust(certD).buildNetwork()
|
||||
|
||||
assertTrue { network.nodes.isEmpty() }
|
||||
assertTrue { network.edgeSet.isEmpty() }
|
||||
assertTrue { network.reverseEdgeSet.isEmpty() }
|
||||
assertTrue { network.edges.isEmpty() }
|
||||
assertTrue { network.reverseEdges.isEmpty() }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -94,7 +94,7 @@ class WebOfTrustTest {
|
|||
|
||||
|
||||
private fun assertHasIssuerAndTarget(
|
||||
certifications: EdgeSet,
|
||||
certifications: Edge,
|
||||
issuer: Fingerprint,
|
||||
target: Fingerprint) {
|
||||
assertEquals(issuer, certifications.issuer.fingerprint)
|
||||
|
@ -119,13 +119,13 @@ class WebOfTrustTest {
|
|||
assertNull(reverseEdge, "Expected no reverse edge on $target from $issuer but got $reverseEdge")
|
||||
}
|
||||
|
||||
private fun getEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): EdgeSet? {
|
||||
val edges = network.edgeSet[issuer] ?: return null
|
||||
private fun getEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): Edge? {
|
||||
val edges = network.edges[issuer] ?: return null
|
||||
return edges.find { target == it.target.fingerprint }
|
||||
}
|
||||
|
||||
private fun getReverseEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): EdgeSet? {
|
||||
val revEdges = network.reverseEdgeSet[target] ?: return null
|
||||
private fun getReverseEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): Edge? {
|
||||
val revEdges = network.reverseEdges[target] ?: return null
|
||||
return revEdges.find { issuer == it.issuer.fingerprint }
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import org.pgpainless.wot.query.Roots
|
|||
import org.pgpainless.wot.query.filter.IdempotentCertificationFilter
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
import org.pgpainless.wot.network.Network
|
||||
import org.pgpainless.wot.network.Path
|
||||
import org.pgpainless.wot.query.Path
|
||||
import org.pgpainless.wot.query.Root
|
||||
import java.io.File
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
package org.pgpainless.wot.api
|
||||
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
import org.pgpainless.wot.network.Paths
|
||||
import org.pgpainless.wot.query.Paths
|
||||
|
||||
/**
|
||||
* Authenticate a binding.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
package org.pgpainless.wot.api
|
||||
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
import org.pgpainless.wot.network.Paths
|
||||
import org.pgpainless.wot.query.Paths
|
||||
|
||||
interface IdentifyAPI {
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.pgpainless.wot.api
|
||||
|
||||
import org.pgpainless.wot.network.Paths
|
||||
import org.pgpainless.wot.query.Paths
|
||||
|
||||
interface ListAPI {
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.pgpainless.wot.api
|
||||
|
||||
import org.pgpainless.wot.network.Paths
|
||||
import org.pgpainless.wot.query.Paths
|
||||
|
||||
interface LookupAPI {
|
||||
|
||||
|
|
|
@ -4,56 +4,110 @@
|
|||
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* A [Edge] is a signature issued by one certificate over a datum on another target certificate.
|
||||
* Such a datum could be either a user-id, or the primary key of the target certificate.
|
||||
* An [Edge] comprises a set of signatures ([EdgeComponent]) made by the same issuer, on the same target certificate.
|
||||
*
|
||||
* @param issuer synopsis of the certificate that issued the [Edge]
|
||||
* @param target synopsis of the certificate that is target of this [Edge]
|
||||
* @param userId optional user-id. If this is null, the [Edge] is made over the primary key of the target.
|
||||
* @param creationTime creation time of the [Edge]
|
||||
* @param expirationTime optional expiration time of the [Edge]
|
||||
* @param exportable if false, the certification is marked as "not exportable"
|
||||
* @param trustAmount amount of trust the issuer places in the binding
|
||||
* @param trustDepth degree to which the issuer trusts the target as trusted introducer
|
||||
* @param regexes regular expressions for user-ids which the target is allowed to introduce
|
||||
* @param issuer synopsis of the certificate that issued the [Certifications][EdgeComponent]
|
||||
* @param target synopsis of the certificate that is targeted by the [Certifications][EdgeComponent]
|
||||
* @param components [Map] keyed by user-ids, whose values are [Lists][List] of
|
||||
* [EdgeComponents][EdgeComponent] that are calculated over the key user-id. Note, that the key can also be null for
|
||||
* [EdgeComponents][EdgeComponent] over the targets primary key.
|
||||
*/
|
||||
data class Edge(
|
||||
class Edge(
|
||||
val issuer: Node,
|
||||
val target: Node,
|
||||
val userId: String?,
|
||||
val creationTime: Date,
|
||||
val expirationTime: Date?,
|
||||
val exportable: Boolean,
|
||||
val trustAmount: Int,
|
||||
val trustDepth: Depth,
|
||||
val regexes: RegexSet
|
||||
) {
|
||||
components: Map<String?, List<EdgeComponent>>) {
|
||||
|
||||
/**
|
||||
* Construct a [Edge] with default values. The result is non-expiring, will be exportable and has a
|
||||
* trust amount of 120, a depth of 0 and a wildcard regex.
|
||||
*
|
||||
* @param issuer synopsis of the certificate that issued the [Edge]
|
||||
* @param target synopsis of the certificate that is target of this [Edge]
|
||||
* @param targetUserId optional user-id. If this is null, the [Edge] is made over the primary key of the target.
|
||||
* @param creationTime creation time of the [Edge]
|
||||
*/
|
||||
constructor(
|
||||
issuer: Node,
|
||||
target: Node,
|
||||
targetUserId: String? = null,
|
||||
creationTime: Date) :
|
||||
this(issuer, target, targetUserId, creationTime, null, true, 120, Depth.limited(0), RegexSet.wildcard())
|
||||
|
||||
override fun toString(): String {
|
||||
return if (trustDepth.limit == 0)
|
||||
"${issuer.fingerprint} certifies binding: $userId <-> ${target.fingerprint} [$trustAmount]"
|
||||
else {
|
||||
val scope = if (regexes.regexStrings.isEmpty()) "" else ", scope: $regexes"
|
||||
"${issuer.fingerprint} delegates to ${target.fingerprint} [$trustAmount, depth $trustDepth$scope]"
|
||||
init {
|
||||
components.forEach { (_, certifications) ->
|
||||
certifications.forEach {
|
||||
add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val _certifications: MutableMap<String?, MutableList<EdgeComponent>> = mutableMapOf()
|
||||
val components: Map<String?, List<EdgeComponent>>
|
||||
get() = _certifications.toMutableMap()
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Create an empty [Edge].
|
||||
*
|
||||
* @param issuer origin of the [Edge].
|
||||
* @param target targeted of the [Edge].
|
||||
*/
|
||||
@JvmStatic
|
||||
fun empty(issuer: Node, target: Node): Edge {
|
||||
return Edge(issuer, target, HashMap())
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a [Edge] from a single [EdgeComponent].
|
||||
*
|
||||
* @param edgeComponent edgeComponent
|
||||
*/
|
||||
@JvmStatic
|
||||
fun fromCertification(edgeComponent: EdgeComponent): Edge {
|
||||
val set = empty(edgeComponent.issuer, edgeComponent.target)
|
||||
set.add(edgeComponent)
|
||||
return set
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the given [Edge] into this.
|
||||
* This method copies all [EdgeComponents][EdgeComponent] from the other [Edge] into [components].
|
||||
*
|
||||
* @param other [Edge] with the same issuer and target as this object.
|
||||
*/
|
||||
fun merge(other: Edge) {
|
||||
if (other == this) {
|
||||
return
|
||||
}
|
||||
|
||||
require(issuer.fingerprint == other.issuer.fingerprint) { "Issuer fingerprint mismatch." }
|
||||
require(target.fingerprint == other.target.fingerprint) { "Target fingerprint mismatch." }
|
||||
|
||||
for (userId in other.components.keys) {
|
||||
for (certification in other.components[userId]!!) {
|
||||
add(certification)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single [EdgeComponent] into this objects [components].
|
||||
* Adding multiple [EdgeComponents][EdgeComponent] for the same datum, but with different creation times results in
|
||||
* only the most recent [EdgeComponent(s)][EdgeComponent] to be preserved.
|
||||
*
|
||||
* @param edgeComponent [EdgeComponent] with the same issuer fingerprint and target fingerprint as this object.
|
||||
*/
|
||||
fun add(edgeComponent: EdgeComponent) {
|
||||
require(issuer.fingerprint == edgeComponent.issuer.fingerprint) { "Issuer fingerprint mismatch." }
|
||||
require(target.fingerprint == edgeComponent.target.fingerprint) { "Target fingerprint mismatch." }
|
||||
|
||||
val certificationsForUserId = _certifications.getOrPut(edgeComponent.userId) { mutableListOf() }
|
||||
if (certificationsForUserId.isEmpty()) {
|
||||
certificationsForUserId.add(edgeComponent)
|
||||
return
|
||||
}
|
||||
|
||||
val existing = certificationsForUserId[0]
|
||||
// if existing is older than this edgeComponent
|
||||
if (existing.creationTime.before(edgeComponent.creationTime)) {
|
||||
// throw away older certifications
|
||||
certificationsForUserId.clear()
|
||||
}
|
||||
// If this edgeComponent is newest (or equally old!)
|
||||
if (!existing.creationTime.after(edgeComponent.creationTime)) {
|
||||
certificationsForUserId.add(edgeComponent)
|
||||
}
|
||||
// else this edgeComponent is older, so don't add it
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return components.map { it.value }.flatten().joinToString("\n")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* An [EdgeComponent] represents a signature issued by one certificate over a datum on another target certificate.
|
||||
* Such a datum could be either a user-id, or the primary key of the target certificate.
|
||||
*
|
||||
* @param issuer certificate that issued the signature
|
||||
* @param target certificate that is target of this signature
|
||||
* @param userId optional user-id. If this is null, the signature is made over the primary key of the target.
|
||||
* @param creationTime creation time of the signature
|
||||
* @param expirationTime optional expiration time of the signature
|
||||
* @param exportable if false, the signtaure is marked as "not exportable"
|
||||
* @param trustAmount amount of trust the issuer places in the binding
|
||||
* @param trustDepth degree to which the issuer trusts the target as trusted introducer
|
||||
* @param regexes regular expressions for user-ids which the target is allowed to introduce
|
||||
*/
|
||||
data class EdgeComponent(
|
||||
val issuer: Node,
|
||||
val target: Node,
|
||||
val userId: String?,
|
||||
val creationTime: Date,
|
||||
val expirationTime: Date?,
|
||||
val exportable: Boolean,
|
||||
val trustAmount: Int,
|
||||
val trustDepth: Depth,
|
||||
val regexes: RegexSet
|
||||
) {
|
||||
|
||||
/**
|
||||
* Construct an [EdgeComponent] with default values. The result is non-expiring, will be exportable and has a
|
||||
* trust amount of 120, a depth of 0 and a wildcard regex.
|
||||
*
|
||||
* @param issuer certificate that issued the signature
|
||||
* @param target certificate that is target of this signature
|
||||
* @param targetUserId optional user-id. If this is null, the signature is made over the primary key of the target.
|
||||
* @param creationTime creation time of the signature
|
||||
*/
|
||||
constructor(
|
||||
issuer: Node,
|
||||
target: Node,
|
||||
targetUserId: String? = null,
|
||||
creationTime: Date) :
|
||||
this(issuer, target, targetUserId, creationTime, null, true, 120, Depth.limited(0), RegexSet.wildcard())
|
||||
|
||||
override fun toString(): String {
|
||||
return if (trustDepth.limit == 0)
|
||||
"${issuer.fingerprint} certifies binding: $userId <-> ${target.fingerprint} [$trustAmount]"
|
||||
else {
|
||||
val scope = if (regexes.regexStrings.isEmpty()) "" else ", scope: $regexes"
|
||||
"${issuer.fingerprint} delegates to ${target.fingerprint} [$trustAmount, depth $trustDepth$scope]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
/**
|
||||
* A [EdgeSet] is a set of [Certifications][Edge] made by the same issuer, on the same
|
||||
* target certificate.
|
||||
* In some sense, a [EdgeSet] can be considered an edge in the web of trust.
|
||||
*
|
||||
* @param issuer synopsis of the certificate that issued the [Certifications][Edge]
|
||||
* @param target synopsis of the certificate that is targeted by the [Certifications][Edge]
|
||||
* @param certifications [Map] keyed by user-ids, whose values are [Lists][List] of
|
||||
* [Certifications][Edge] that are calculated over the key user-id. Note, that the key can also be null for
|
||||
* [Certifications][Edge] over the targets primary key.
|
||||
*/
|
||||
class EdgeSet(
|
||||
val issuer: Node,
|
||||
val target: Node,
|
||||
certifications: Map<String?, List<Edge>>) {
|
||||
|
||||
init {
|
||||
certifications.forEach { (_, certifications) ->
|
||||
certifications.forEach {
|
||||
add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val _certifications: MutableMap<String?, MutableList<Edge>> = mutableMapOf()
|
||||
val certifications: Map<String?, List<Edge>>
|
||||
get() = _certifications.toMutableMap()
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Create an empty [EdgeSet].
|
||||
*
|
||||
* @param issuer the certificate that issued the [Certifications][Edge].
|
||||
* @param target the certificate that is targeted by the [Certifications][Edge].
|
||||
*/
|
||||
@JvmStatic
|
||||
fun empty(issuer: Node, target: Node): EdgeSet {
|
||||
return EdgeSet(issuer, target, HashMap())
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a [EdgeSet] from a single [Edge].
|
||||
*
|
||||
* @param edge edge
|
||||
*/
|
||||
@JvmStatic
|
||||
fun fromCertification(edge: Edge): EdgeSet {
|
||||
val set = empty(edge.issuer, edge.target)
|
||||
set.add(edge)
|
||||
return set
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the given [EdgeSet] into this.
|
||||
* This method copies all [Certifications][Edge] from the other [EdgeSet] into [certifications].
|
||||
*
|
||||
* @param other [EdgeSet] with the same issuer fingerprint and target fingerprint as this object.
|
||||
*/
|
||||
fun merge(other: EdgeSet) {
|
||||
if (other == this) {
|
||||
return
|
||||
}
|
||||
|
||||
require(issuer.fingerprint == other.issuer.fingerprint) { "Issuer fingerprint mismatch." }
|
||||
require(target.fingerprint == other.target.fingerprint) { "Target fingerprint mismatch." }
|
||||
|
||||
for (userId in other.certifications.keys) {
|
||||
for (certification in other.certifications[userId]!!) {
|
||||
add(certification)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single [Edge] into this objects [certifications].
|
||||
* Adding multiple [Certifications][Edge] for the same datum, but with different creation times results in
|
||||
* only the most recent [Edge(s)][Edge] to be preserved.
|
||||
*
|
||||
* @param edge [Edge] with the same issuer fingerprint and target fingerprint as this object.
|
||||
*/
|
||||
fun add(edge: Edge) {
|
||||
require(issuer.fingerprint == edge.issuer.fingerprint) { "Issuer fingerprint mismatch." }
|
||||
require(target.fingerprint == edge.target.fingerprint) { "Target fingerprint mismatch." }
|
||||
|
||||
val certificationsForUserId = _certifications.getOrPut(edge.userId) { mutableListOf() }
|
||||
if (certificationsForUserId.isEmpty()) {
|
||||
certificationsForUserId.add(edge)
|
||||
return
|
||||
}
|
||||
|
||||
val existing = certificationsForUserId[0]
|
||||
// if existing is older than this edge
|
||||
if (existing.creationTime.before(edge.creationTime)) {
|
||||
// throw away older certifications
|
||||
certificationsForUserId.clear()
|
||||
}
|
||||
// If this edge is newest (or equally old!)
|
||||
if (!existing.creationTime.after(edge.creationTime)) {
|
||||
certificationsForUserId.add(edge)
|
||||
}
|
||||
// else this edge is older, so don't add it
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return certifications.map { it.value }.flatten().joinToString("\n")
|
||||
}
|
||||
}
|
|
@ -5,20 +5,20 @@
|
|||
package org.pgpainless.wot.network
|
||||
|
||||
/**
|
||||
* A network consists of nodes, and edgeSet between them.
|
||||
* For the Web of Trust, nodes consist of [CertSynopses][Node], while the edgeSet between the nodes are
|
||||
* [CertificationSets][EdgeSet].
|
||||
* A network consists of nodes, and edges between them.
|
||||
* In the Web-of-Trust, a [Node] corresponds to a certificate, while an [Edge] comprises all [EdgeComponents][EdgeComponent]
|
||||
* (certifications) between two certificates, separated by their datum (e.g. the certified user-id).
|
||||
*
|
||||
* @constructor creates a new network
|
||||
* @param nodes contains a [Map] of [Node] keyed by their [Fingerprint]
|
||||
* @param edgeSet [Map] keyed by the [fingerprint][Fingerprint] of an issuer, whose values are [Lists][List] containing all edgeSet originating from the issuer.
|
||||
* @param reverseEdgeSet [Map] keyed by the [fingerprint][Fingerprint] of a target, whose values are [Lists][List] containing all edgeSet pointing to the target
|
||||
* @param nodes associate [Nodes][Node] with their [Fingerprint]
|
||||
* @param edges map of [Edges][Edge] keyed by their issuers [Fingerprint]
|
||||
* @param reverseEdges map of [Edges][Edge] keyed by their targets [Fingerprint]
|
||||
* @param referenceTime reference time at which the [Network] was built
|
||||
*/
|
||||
class Network(
|
||||
val nodes: Map<Fingerprint, Node>,
|
||||
val edgeSet: Map<Fingerprint, List<EdgeSet>>,
|
||||
val reverseEdgeSet: Map<Fingerprint, List<EdgeSet>>,
|
||||
val edges: Map<Fingerprint, List<Edge>>,
|
||||
val reverseEdges: Map<Fingerprint, List<Edge>>,
|
||||
val referenceTime: ReferenceTime) {
|
||||
|
||||
companion object {
|
||||
|
@ -34,31 +34,31 @@ class Network(
|
|||
}
|
||||
|
||||
/**
|
||||
* The total number of edgeSet on the network.
|
||||
* The total number of edges on the network.
|
||||
*
|
||||
* @return number of edgeSet
|
||||
* @return number of edges
|
||||
*/
|
||||
val numberOfEdges: Int
|
||||
get() {
|
||||
return edgeSet.values.sumOf { it.size }
|
||||
return edges.values.sumOf { it.size }
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of signatures the network comprises.
|
||||
* The total number of individual [EdgeComponents][EdgeComponent] the network comprises.
|
||||
*/
|
||||
val numberOfSignatures: Int
|
||||
get() {
|
||||
return edgeSet.values
|
||||
return edges.values
|
||||
.flatten()
|
||||
.flatMap { it.certifications.values }
|
||||
.flatMap { it.components.values }
|
||||
.sumOf { it.size }
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val sb = StringBuilder()
|
||||
sb.append("Network with ${nodes.size} nodes, $numberOfEdges edgeSet:\n")
|
||||
sb.append("Network with ${nodes.size} nodes, $numberOfEdges edges:\n")
|
||||
for (issuer in nodes.keys) {
|
||||
val outEdges = edgeSet[issuer] ?: continue
|
||||
val outEdges = edges[issuer] ?: continue
|
||||
for (edge in outEdges) {
|
||||
sb.appendLine(edge)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class Network(
|
|||
|
||||
class Builder internal constructor() {
|
||||
val nodes: MutableMap<Fingerprint, Node> = mutableMapOf()
|
||||
private val protoEdgeSet: MutableMap<Pair<Fingerprint, Fingerprint>, EdgeSet> = mutableMapOf()
|
||||
private val protoEdgeSet: MutableMap<Pair<Fingerprint, Fingerprint>, Edge> = mutableMapOf()
|
||||
private var referenceTime: ReferenceTime = ReferenceTime.now()
|
||||
|
||||
fun addNode(node: Node): Builder {
|
||||
|
@ -80,10 +80,10 @@ class Network(
|
|||
return nodes[fingerprint]
|
||||
}
|
||||
|
||||
fun addEdge(edge: Edge): Builder {
|
||||
protoEdgeSet.getOrPut(Pair(edge.issuer.fingerprint, edge.target.fingerprint)) {
|
||||
EdgeSet.empty(edge.issuer, edge.target)
|
||||
}.add(edge)
|
||||
fun addEdge(edgeComponent: EdgeComponent): Builder {
|
||||
protoEdgeSet.getOrPut(Pair(edgeComponent.issuer.fingerprint, edgeComponent.target.fingerprint)) {
|
||||
Edge.empty(edgeComponent.issuer, edgeComponent.target)
|
||||
}.add(edgeComponent)
|
||||
return this
|
||||
}
|
||||
|
||||
|
@ -93,8 +93,8 @@ class Network(
|
|||
}
|
||||
|
||||
fun build(): Network {
|
||||
val edgeSet = mutableMapOf<Fingerprint, MutableList<EdgeSet>>()
|
||||
val revEdgeSet = mutableMapOf<Fingerprint, MutableList<EdgeSet>>()
|
||||
val edgeSet = mutableMapOf<Fingerprint, MutableList<Edge>>()
|
||||
val revEdgeSet = mutableMapOf<Fingerprint, MutableList<Edge>>()
|
||||
|
||||
protoEdgeSet.forEach { (pair, certificationSet) ->
|
||||
edgeSet.getOrPut(pair.first) {
|
||||
|
|
|
@ -2,21 +2,24 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.network
|
||||
package org.pgpainless.wot.query
|
||||
|
||||
import org.pgpainless.wot.network.Depth
|
||||
import org.pgpainless.wot.network.EdgeComponent
|
||||
import org.pgpainless.wot.network.Node
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* A [Path] comprises a root [Node], a list of edgeSet ([Certifications][Edge]), as well as a
|
||||
* A [Path] comprises a root [Node], a list of edges (selected [EdgeComponents][EdgeComponent]), as well as a
|
||||
* residual depth.
|
||||
*
|
||||
* @param root root of the path
|
||||
* @param edges list of edgeSet from the root to the target
|
||||
* @param edges list of edges from the root to the target
|
||||
* @param residualDepth residual depth that is decreased each time another edge is appended
|
||||
*/
|
||||
class Path(
|
||||
val root: Node,
|
||||
private val edges: MutableList<Edge>,
|
||||
private val edges: MutableList<EdgeComponent>,
|
||||
var residualDepth: Depth
|
||||
) {
|
||||
|
||||
|
@ -27,7 +30,7 @@ class Path(
|
|||
* @param root trust root
|
||||
*/
|
||||
constructor(root: Node) : this(
|
||||
root, mutableListOf<Edge>(), Depth.unconstrained())
|
||||
root, mutableListOf<EdgeComponent>(), Depth.unconstrained())
|
||||
|
||||
/**
|
||||
* Current target of the path.
|
||||
|
@ -43,14 +46,14 @@ class Path(
|
|||
}
|
||||
|
||||
/**
|
||||
* List of [CertSynopses][Node] (nodes) of the path.
|
||||
* The first entry is the [root]. The other entries are the targets of the edgeSet.
|
||||
* List of [Nodes][Node] on the path.
|
||||
* The first entry is the [root]. The other entries are the targets of the edges.
|
||||
*/
|
||||
val certificates: List<Node>
|
||||
get() {
|
||||
val certs: MutableList<Node> = mutableListOf(root)
|
||||
for (certification in edges) {
|
||||
certs.add(certification.target)
|
||||
for (edge in edges) {
|
||||
certs.add(edge.target)
|
||||
}
|
||||
return certs
|
||||
}
|
||||
|
@ -63,9 +66,9 @@ class Path(
|
|||
get() = edges.size + 1
|
||||
|
||||
/**
|
||||
* List of edgeSet.
|
||||
* List of edge components.
|
||||
*/
|
||||
val certifications: List<Edge>
|
||||
val certifications: List<EdgeComponent>
|
||||
get() = edges.toList()
|
||||
|
||||
/**
|
||||
|
@ -88,10 +91,10 @@ class Path(
|
|||
*
|
||||
* @throws IllegalArgumentException if the target at the end of the path is not equal to the issuer of the edge.
|
||||
* @throws IllegalArgumentException if the path runs out of residual depth
|
||||
* @throws IllegalArgumentException if the addition of the [Edge] would result in a cyclic path
|
||||
* @throws IllegalArgumentException if the addition of the [EdgeComponent] would result in a cyclic path
|
||||
*/
|
||||
fun append(aEdge: Edge) {
|
||||
require(target.fingerprint == aEdge.issuer.fingerprint) {
|
||||
fun append(component: EdgeComponent) {
|
||||
require(target.fingerprint == component.issuer.fingerprint) {
|
||||
"Cannot append edge to path: Path's tail is not issuer of the edge."
|
||||
}
|
||||
require(residualDepth.isUnconstrained() || residualDepth.limit!! > 0) {
|
||||
|
@ -99,26 +102,26 @@ class Path(
|
|||
}
|
||||
|
||||
// root is c's target -> illegal cycle
|
||||
var cyclic = root.fingerprint == aEdge.target.fingerprint
|
||||
var cyclic = root.fingerprint == component.target.fingerprint
|
||||
for ((i, edge) in edges.withIndex()) {
|
||||
if (cyclic) {
|
||||
break
|
||||
}
|
||||
// existing edge points to c's target -> illegal cycle
|
||||
if (aEdge.target.fingerprint == edge.target.fingerprint) {
|
||||
if (component.target.fingerprint == edge.target.fingerprint) {
|
||||
cyclic = if (edges.lastIndex != i) {
|
||||
// Cycle in the middle of the ~~street~~ path
|
||||
true
|
||||
} else {
|
||||
// Not a cycle, if we point to a different user-id
|
||||
aEdge.userId == edge.userId
|
||||
component.userId == edge.userId
|
||||
}
|
||||
}
|
||||
}
|
||||
require(!cyclic) { "Adding the edge to the path would create a cycle." }
|
||||
|
||||
residualDepth = aEdge.trustDepth.min(residualDepth.decrease(1))
|
||||
edges.add(aEdge)
|
||||
residualDepth = component.trustDepth.min(residualDepth.decrease(1))
|
||||
edges.add(component)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.network
|
||||
package org.pgpainless.wot.query
|
||||
|
||||
/**
|
||||
* List of individual [Paths][Path].
|
|
@ -48,7 +48,7 @@ internal class Cost(
|
|||
// We perform a Dijkstra in reserve from the target towards the roots.
|
||||
internal data class ForwardPointer(
|
||||
// If null, then the target.
|
||||
val next: Edge?
|
||||
val next: EdgeComponent?
|
||||
)
|
||||
|
||||
class Query(
|
||||
|
@ -174,7 +174,7 @@ class Query(
|
|||
///
|
||||
/// # Algorithm
|
||||
///
|
||||
/// This algorithm reverses the edgeSet in the network and then
|
||||
/// This algorithm reverses the edges in the network and then
|
||||
/// executes a variant of [Dijkstra's shortest path algorithm].
|
||||
/// The algorithm sets the initial node to be the target and works
|
||||
/// outwards. Consider the following network:
|
||||
|
@ -362,7 +362,7 @@ class Query(
|
|||
var depth: Int = if (selfSigned) 1 else 0
|
||||
|
||||
while (fp.next != null) {
|
||||
val c: Edge = fp.next!! // FIXME
|
||||
val c: EdgeComponent = fp.next!! // FIXME
|
||||
|
||||
val a = c.trustAmount
|
||||
val d = c.trustDepth
|
||||
|
@ -430,8 +430,8 @@ class Query(
|
|||
// Get signeeFp
|
||||
|
||||
// Not limiting by required_depth, because 'network' doesn't expose an interface for this
|
||||
val edges: List<EdgeSet> =
|
||||
network.reverseEdgeSet[signeeFpr].orEmpty() // "certifications_of"
|
||||
val edges: List<Edge> =
|
||||
network.reverseEdges[signeeFpr].orEmpty() // "certifications_of"
|
||||
|
||||
if (edges.isEmpty()) {
|
||||
// Nothing certified it. The path is a dead end.
|
||||
|
@ -446,7 +446,7 @@ class Query(
|
|||
|
||||
for (certification in edges
|
||||
.map { cs ->
|
||||
cs.certifications
|
||||
cs.components
|
||||
.map { it.value }.flatten()
|
||||
}.flatten()) {
|
||||
|
||||
|
@ -472,7 +472,7 @@ class Query(
|
|||
|
||||
|
||||
if (fv.amount == 0) {
|
||||
logger.debug(" Edge amount is 0, skipping")
|
||||
logger.debug(" EdgeComponent amount is 0, skipping")
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -481,20 +481,20 @@ class Query(
|
|||
&& certification.userId != targetUserid) {
|
||||
assert(signeeFp.next == null)
|
||||
|
||||
logger.debug(" Edge certifies target, but for the wrong user id (want: {}, got: {})",
|
||||
logger.debug(" EdgeComponent certifies target, but for the wrong user id (want: {}, got: {})",
|
||||
targetUserid, certification.userId)
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fv.depth < Depth.auto(signeeFpCost.depth)) {
|
||||
logger.debug(" Edge does not have enough depth ({}, needed: {}), skipping", fv.depth, signeeFpCost.depth)
|
||||
logger.debug(" EdgeComponent does not have enough depth ({}, needed: {}), skipping", fv.depth, signeeFpCost.depth)
|
||||
continue;
|
||||
}
|
||||
|
||||
val re = fv.regexps
|
||||
if ((re != null) && !re.matches(targetUserid)) {
|
||||
logger.debug(" Edge's re does not match target User ID, skipping.")
|
||||
logger.debug(" EdgeComponent's re does not match target User ID, skipping.")
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -538,7 +538,7 @@ class Query(
|
|||
cn?.target ?: "target", currentFpCost.amount, currentFpCost.depth)
|
||||
|
||||
// We prefer a shorter path (in terms of
|
||||
// edgeSet) as this allows us to reach more of
|
||||
// edges) as this allows us to reach more of
|
||||
// the graph.
|
||||
//
|
||||
// If the path length is equal, we prefer the
|
||||
|
@ -615,7 +615,7 @@ class Query(
|
|||
//
|
||||
// XXX: Self-signatures should be first class and not
|
||||
// synthesized like this on the fly.
|
||||
val selfsig = Edge(
|
||||
val selfsig = EdgeComponent(
|
||||
target, target, targetUserid,
|
||||
|
||||
// FIXME! Use userid binding signature by default, reference time only as fallback:
|
||||
|
@ -651,7 +651,7 @@ class Query(
|
|||
var amount = 120;
|
||||
|
||||
// nodes[0] is the root; nodes[nodes.len() - 1] is the target.
|
||||
val nodes: MutableList<Edge> = mutableListOf();
|
||||
val nodes: MutableList<EdgeComponent> = mutableListOf();
|
||||
while (true) {
|
||||
val c = fp.next ?: break
|
||||
|
||||
|
@ -673,7 +673,7 @@ class Query(
|
|||
if (selfSigned) {
|
||||
val tail = nodes.last()
|
||||
if (tail.userId != targetUserid) {
|
||||
val selfsig = Edge(target, target, targetUserid, Date());
|
||||
val selfsig = EdgeComponent(target, target, targetUserid, Date());
|
||||
nodes.add(selfsig);
|
||||
}
|
||||
}
|
||||
|
@ -725,7 +725,7 @@ class Query(
|
|||
// .unwrap_or("<missing User ID>".into());
|
||||
// t!(" <{}, {}>: {}",
|
||||
// fpr, userid,
|
||||
// format!("{} trust amount (max: {}), {} edgeSet",
|
||||
// format!("{} trust amount (max: {}), {} edges",
|
||||
// amount, path.amount(),
|
||||
// path.len() - 1));
|
||||
// }
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.pgpainless.wot.query.filter
|
||||
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.EdgeComponent
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
|
||||
class CapCertificateFilter() : CertificationFilter {
|
||||
|
@ -12,7 +12,7 @@ class CapCertificateFilter() : CertificationFilter {
|
|||
// A certificate's trust amount will be limited to this amount.
|
||||
private val caps: HashMap<Fingerprint, Int> = hashMapOf()
|
||||
|
||||
override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
override fun cost(c: EdgeComponent, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
caps[c.issuer.fingerprint]?.let {
|
||||
if (it < values.amount) {
|
||||
values.amount = it
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.pgpainless.wot.query.filter
|
||||
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.EdgeComponent
|
||||
import org.pgpainless.wot.network.Depth
|
||||
import org.pgpainless.wot.network.RegexSet
|
||||
|
||||
|
@ -33,7 +33,7 @@ interface CertificationFilter {
|
|||
*
|
||||
* If the function returns `false`, the certification should be skipped.
|
||||
*/
|
||||
fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
fun cost(c: EdgeComponent, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.pgpainless.wot.query.filter
|
||||
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.EdgeComponent
|
||||
|
||||
/**
|
||||
* A filter that chains multiple filters together.
|
||||
|
@ -15,7 +15,7 @@ import org.pgpainless.wot.network.Edge
|
|||
*/
|
||||
class ChainFilter(val filters: MutableList<CertificationFilter>) : CertificationFilter {
|
||||
|
||||
override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
override fun cost(c: EdgeComponent, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
|
||||
// If any inner filter returns `false`, immediately return false
|
||||
return !this.filters.any { !it.cost(c, values, ignoreRegexps) }
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
|
||||
package org.pgpainless.wot.query.filter
|
||||
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.EdgeComponent
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
import org.pgpainless.wot.network.Path
|
||||
import org.pgpainless.wot.query.Path
|
||||
|
||||
class SuppressCertificationFilter() : CertificationFilter {
|
||||
// A certification's trust amount will be suppressed by this amount.
|
||||
private val amount: HashMap<Pair<Fingerprint, Fingerprint>, Int> = hashMapOf()
|
||||
|
||||
override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
override fun cost(c: EdgeComponent, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
amount[Pair(c.issuer.fingerprint, c.issuer.fingerprint)]?.let { suppress ->
|
||||
values.amount = if (values.amount > suppress) {
|
||||
values.amount - suppress
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.pgpainless.wot.query.filter
|
||||
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.EdgeComponent
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,7 @@ class SuppressIssuerFilter() : CertificationFilter {
|
|||
// A certification's trust amount will be suppressed by this amount.
|
||||
private val amount: HashMap<Fingerprint, Int> = hashMapOf()
|
||||
|
||||
override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
override fun cost(c: EdgeComponent, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
amount[c.issuer.fingerprint]?.let { suppress ->
|
||||
values.amount = if (values.amount > suppress) {
|
||||
values.amount - suppress
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.pgpainless.wot.query.filter
|
||||
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.EdgeComponent
|
||||
import org.pgpainless.wot.network.Depth
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ import org.pgpainless.wot.network.Depth
|
|||
* This filter can be used to view a network as a 'certification network'.
|
||||
*/
|
||||
class TrustedIntroducerFilter : CertificationFilter {
|
||||
override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
override fun cost(c: EdgeComponent, values: FilterValues, ignoreRegexps: Boolean): Boolean {
|
||||
values.depth = Depth.unconstrained()
|
||||
if (!ignoreRegexps) {
|
||||
values.regexps = null
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package org.pgpainless.wot.dijkstra.sq
|
||||
|
||||
import org.pgpainless.wot.network.RegexSet
|
||||
import kotlin.test.Test
|
||||
|
||||
class RegexSetTest {
|
||||
|
||||
@Test
|
||||
fun simpleMatch() {
|
||||
val stringList: List<String> = listOf("<[^>]+[@.]foobank\\.com>$")
|
||||
val rs = RegexSet.fromExpressionList(stringList);
|
||||
|
||||
assert(rs.matches("Foo Bank Employee <employee@foobank.com>"))
|
||||
assert(rs.matches("<employee@foobank.com>"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun simpleNonMatch() {
|
||||
val stringList: List<String> = listOf("<[^>]+[@.]foobank\\.com>$")
|
||||
val rs = RegexSet.fromExpressionList(stringList);
|
||||
|
||||
assert(!rs.matches("Bar Bank Employee <employee@barbank.com>"))
|
||||
assert(!rs.matches("<employee@barbank.com>"))
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
|
@ -1,14 +1,10 @@
|
|||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.wot.network.Node
|
||||
import org.pgpainless.wot.network.Edge
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
import org.pgpainless.wot.network.RevocationState
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class EdgeTest {
|
||||
class EdgeComponentTest {
|
||||
|
||||
private val alice = Node(
|
||||
Fingerprint("A"),
|
||||
|
@ -28,21 +24,21 @@ class EdgeTest {
|
|||
|
||||
@Test
|
||||
fun `verify result of toString() on certification`() {
|
||||
val edge = Edge(alice, bob, "Bob <bob@example.org>", Date())
|
||||
val edgeComponent = EdgeComponent(alice, bob, "Bob <bob@example.org>", Date())
|
||||
assertEquals("A certifies binding: Bob <bob@example.org> <-> B [120]",
|
||||
edge.toString())
|
||||
edgeComponent.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify result of toString() on delegation`() {
|
||||
val delegation = Edge(alice, bob, null, Date())
|
||||
val delegation = EdgeComponent(alice, bob, null, Date())
|
||||
assertEquals("A certifies binding: null <-> B [120]",
|
||||
delegation.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify result of toString() on delegation with userId-less issuer`() {
|
||||
val delegation = Edge(charlie, bob, null, Date())
|
||||
val delegation = EdgeComponent(charlie, bob, null, Date())
|
||||
assertEquals("C certifies binding: null <-> B [120]",
|
||||
delegation.toString())
|
||||
}
|
|
@ -2,106 +2,105 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pgpainless.wot.network.*
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class EdgeSetTest {
|
||||
class EdgeTest {
|
||||
|
||||
private val alice = Node(Fingerprint("A"), null, RevocationState.notRevoked(), mapOf())
|
||||
private val bob = Node(Fingerprint("B"), null, RevocationState.notRevoked(), mapOf())
|
||||
private val charlie = Node(Fingerprint("C"), null, RevocationState.notRevoked(), mapOf())
|
||||
|
||||
private val aliceSignsBob = Edge(alice, bob, null, Date())
|
||||
private val aliceSignsBobUserId = Edge(alice, bob, "Bob <bob@example.org>", Date())
|
||||
private val aliceSignsCharlie = Edge(alice, charlie, null, Date())
|
||||
private val charlieSignsBob = Edge(charlie, bob, null, Date())
|
||||
private val aliceSignsBob = EdgeComponent(alice, bob, null, Date())
|
||||
private val aliceSignsBobUserId = EdgeComponent(alice, bob, "Bob <bob@example.org>", Date())
|
||||
private val aliceSignsCharlie = EdgeComponent(alice, charlie, null, Date())
|
||||
private val charlieSignsBob = EdgeComponent(charlie, bob, null, Date())
|
||||
|
||||
@Test
|
||||
fun `verify that properties of an empty CertificationSet are also empty`() {
|
||||
val empty = EdgeSet.empty(alice, bob)
|
||||
assert(empty.certifications.isEmpty())
|
||||
val empty = Edge.empty(alice, bob)
|
||||
assert(empty.components.isEmpty())
|
||||
assertEquals(alice, empty.issuer)
|
||||
assertEquals(bob, empty.target)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that add()ing Certification objects works if issuer and target match that of the CertificationSet`() {
|
||||
val set = EdgeSet.empty(alice, bob)
|
||||
val set = Edge.empty(alice, bob)
|
||||
|
||||
set.add(aliceSignsBob)
|
||||
assertTrue {
|
||||
set.certifications.values.any {
|
||||
set.components.values.any {
|
||||
it.contains(aliceSignsBob)
|
||||
}
|
||||
}
|
||||
set.add(aliceSignsBobUserId)
|
||||
assertTrue {
|
||||
set.certifications["Bob <bob@example.org>"]!!.contains(aliceSignsBobUserId)
|
||||
set.components["Bob <bob@example.org>"]!!.contains(aliceSignsBobUserId)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that add()ing another Certification object fails if the issuer mismatches`() {
|
||||
val set = EdgeSet.empty(alice, bob)
|
||||
val set = Edge.empty(alice, bob)
|
||||
assertThrows<IllegalArgumentException> { set.add(charlieSignsBob) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that add()ing another Certification object fails if the target mismatches`() {
|
||||
val set = EdgeSet.empty(alice, bob)
|
||||
val set = Edge.empty(alice, bob)
|
||||
assertThrows<IllegalArgumentException> { set.add(aliceSignsCharlie) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that merge()ing another CertificationSet works if issuer and target match that of the CertificationSet`() {
|
||||
val set = EdgeSet.fromCertification(aliceSignsBob)
|
||||
val others = EdgeSet.fromCertification(aliceSignsBobUserId)
|
||||
val set = Edge.fromCertification(aliceSignsBob)
|
||||
val others = Edge.fromCertification(aliceSignsBobUserId)
|
||||
|
||||
set.merge(others)
|
||||
assertEquals(2, set.certifications.size)
|
||||
assertTrue { set.certifications[null]!!.contains(aliceSignsBob) }
|
||||
assertTrue { set.certifications["Bob <bob@example.org>"]!!.contains(aliceSignsBobUserId) }
|
||||
assertEquals(2, set.components.size)
|
||||
assertTrue { set.components[null]!!.contains(aliceSignsBob) }
|
||||
assertTrue { set.components["Bob <bob@example.org>"]!!.contains(aliceSignsBobUserId) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that merge()ing another CertificationSet with mismatched issuer fails`() {
|
||||
val set = EdgeSet.fromCertification(aliceSignsBob)
|
||||
val issuerMismatch = EdgeSet.fromCertification(charlieSignsBob)
|
||||
val set = Edge.fromCertification(aliceSignsBob)
|
||||
val issuerMismatch = Edge.fromCertification(charlieSignsBob)
|
||||
|
||||
assertThrows<IllegalArgumentException> { set.merge(issuerMismatch) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that merge()ing another CertificationSet with mismatched target fails`() {
|
||||
val set = EdgeSet.fromCertification(aliceSignsBob)
|
||||
val targetMismatch = EdgeSet.fromCertification(aliceSignsCharlie)
|
||||
val set = Edge.fromCertification(aliceSignsBob)
|
||||
val targetMismatch = Edge.fromCertification(aliceSignsCharlie)
|
||||
|
||||
assertThrows<IllegalArgumentException> { set.merge(targetMismatch) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that merge()ing a CertificationSet with itself is idempotent`() {
|
||||
val set = EdgeSet.fromCertification(aliceSignsBob)
|
||||
assertEquals(1, set.certifications.size)
|
||||
val set = Edge.fromCertification(aliceSignsBob)
|
||||
assertEquals(1, set.components.size)
|
||||
set.merge(set)
|
||||
assertEquals(1, set.certifications.size)
|
||||
assertEquals(1, set.components.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that toString() of an empty CertificationSet is the empty string`() {
|
||||
val empty = EdgeSet.empty(alice, bob)
|
||||
val empty = Edge.empty(alice, bob)
|
||||
assertEquals("", empty.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that toString() of a CertificationSet with two Certifications matches our expectations`() {
|
||||
val twoCerts = EdgeSet.fromCertification(aliceSignsBob)
|
||||
val twoCerts = Edge.fromCertification(aliceSignsBob)
|
||||
twoCerts.add(aliceSignsBobUserId)
|
||||
|
||||
assertEquals("A certifies binding: null <-> B [120]\n" +
|
||||
|
@ -112,22 +111,22 @@ class EdgeSetTest {
|
|||
fun `verify that for multiple Certifications over the same datum, only the most recent certifications are preserved`() {
|
||||
val now = Date()
|
||||
val fiveSecondsBefore = Date(now.time - 5000)
|
||||
val old = Edge(alice, bob, "Bob <bob@example.org>", fiveSecondsBefore)
|
||||
val new = Edge(alice, bob, "Bob <bob@example.org>", now)
|
||||
val new2 = Edge(alice, bob, "Bob <bob@example.org>", now, null, true, 44, Depth.auto(10), RegexSet.wildcard())
|
||||
val old = EdgeComponent(alice, bob, "Bob <bob@example.org>", fiveSecondsBefore)
|
||||
val new = EdgeComponent(alice, bob, "Bob <bob@example.org>", now)
|
||||
val new2 = EdgeComponent(alice, bob, "Bob <bob@example.org>", now, null, true, 44, Depth.auto(10), RegexSet.wildcard())
|
||||
|
||||
var set = EdgeSet(alice, bob, mapOf())
|
||||
var set = Edge(alice, bob, mapOf())
|
||||
set.add(old)
|
||||
|
||||
assertEquals(listOf(old), set.certifications["Bob <bob@example.org>"])
|
||||
assertEquals(listOf(old), set.components["Bob <bob@example.org>"])
|
||||
|
||||
set.add(new)
|
||||
assertEquals(listOf(new), set.certifications["Bob <bob@example.org>"])
|
||||
assertEquals(listOf(new), set.components["Bob <bob@example.org>"])
|
||||
|
||||
set.add(new2)
|
||||
assertEquals(listOf(new, new2), set.certifications["Bob <bob@example.org>"])
|
||||
assertEquals(listOf(new, new2), set.components["Bob <bob@example.org>"])
|
||||
|
||||
set.add(old)
|
||||
assertEquals(listOf(new, new2), set.certifications["Bob <bob@example.org>"])
|
||||
assertEquals(listOf(new, new2), set.components["Bob <bob@example.org>"])
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.wot.network.Fingerprint
|
|
@ -2,9 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.pgpainless.wot.network.*
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
|
@ -15,46 +14,46 @@ interface NetworkDSL {
|
|||
/**
|
||||
* Create [Node] from [String] fingerprint.
|
||||
*/
|
||||
fun CertSynopsis(fingerprint: String): Node =
|
||||
fun Node(fingerprint: String): Node =
|
||||
Node(Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf())
|
||||
|
||||
/**
|
||||
* Create [Node] from [String] fingerprint and non-revoked [userId].
|
||||
*/
|
||||
fun CertSynopsis(fingerprint: String, userId: String): Node = Node(
|
||||
fun Node(fingerprint: String, userId: String): Node = Node(
|
||||
Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf(userId to RevocationState.notRevoked()))
|
||||
|
||||
fun CertSynopsis(original: Node, userId: String): Node = Node(
|
||||
fun Node(original: Node, userId: String): Node = Node(
|
||||
original.fingerprint, original.expirationTime, original.revocationState, original.userIds.plus(userId to RevocationState.notRevoked())
|
||||
)
|
||||
|
||||
/**
|
||||
* Create [Edge] from two [Node] nodes.
|
||||
* Create [EdgeComponent] from two [Node] nodes.
|
||||
*/
|
||||
fun Certification(issuer: Node, target: Node): Edge =
|
||||
Edge(issuer, target, null, Date())
|
||||
fun Edge(issuer: Node, target: Node): EdgeComponent =
|
||||
EdgeComponent(issuer, target, null, Date())
|
||||
|
||||
/**
|
||||
* Create [Edge] from two [Node] nodes and a target [userId].
|
||||
* Create [EdgeComponent] from two [Node] nodes and a target [userId].
|
||||
*/
|
||||
fun Certification(issuer: Node, target: Node, userId: String): Edge =
|
||||
Edge(issuer, target, userId, Date())
|
||||
fun Edge(issuer: Node, target: Node, userId: String): EdgeComponent =
|
||||
EdgeComponent(issuer, target, userId, Date())
|
||||
|
||||
fun Certification(issuer: Node, target: Node, amount: Int, depth: Depth): Edge =
|
||||
Edge(issuer, target, null, Date(), null, true, amount, depth, RegexSet.wildcard())
|
||||
fun Edge(issuer: Node, target: Node, amount: Int, depth: Depth): EdgeComponent =
|
||||
EdgeComponent(issuer, target, null, Date(), null, true, amount, depth, RegexSet.wildcard())
|
||||
|
||||
/**
|
||||
* Add a single [Node] built from a [String] fingerprint to the builder.
|
||||
*/
|
||||
fun Network.Builder.addNode(fingerprint: String): Network.Builder {
|
||||
return addNode(CertSynopsis(fingerprint))
|
||||
return addNode(Node(fingerprint))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single [Node] built from a [String] fingerprint and [userId] to the builder.
|
||||
*/
|
||||
fun Network.Builder.addNode(fingerprint: String, userId: String): Network.Builder {
|
||||
return addNode(CertSynopsis(fingerprint, userId))
|
||||
return addNode(Node(fingerprint, userId))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,7 +73,7 @@ interface NetworkDSL {
|
|||
fun Network.Builder.addEdge(issuer: String, target: String): Network.Builder {
|
||||
val issuerNode = nodes[Fingerprint(issuer)]!!
|
||||
val targetNode = nodes[Fingerprint(target)]!!
|
||||
return addEdge(Certification(issuerNode, targetNode))
|
||||
return addEdge(Edge(issuerNode, targetNode))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,7 +84,7 @@ interface NetworkDSL {
|
|||
fun Network.Builder.addEdge(issuer: String, target: String, userId: String): Network.Builder {
|
||||
val issuerNode = nodes[Fingerprint(issuer)]!!
|
||||
val targetNode = nodes[Fingerprint(target)]!!
|
||||
return addEdge(Certification(issuerNode, targetNode, userId))
|
||||
return addEdge(Edge(issuerNode, targetNode, userId))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,9 +92,9 @@ interface NetworkDSL {
|
|||
* a new node for them to the builder.
|
||||
*/
|
||||
fun Network.Builder.buildEdge(issuer: String, target: String): Network.Builder {
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { CertSynopsis(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { CertSynopsis(target) }
|
||||
return addEdge(Certification(issuerNode, targetNode))
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { Node(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { Node(target) }
|
||||
return addEdge(Edge(issuerNode, targetNode))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,51 +104,51 @@ interface NetworkDSL {
|
|||
* the [userId] inserted.
|
||||
*/
|
||||
fun Network.Builder.buildEdge(issuer: String, target: String, userId: String): Network.Builder {
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { CertSynopsis(issuer)}
|
||||
val targetNode = CertSynopsis(nodes.getOrPut(Fingerprint(target)) { CertSynopsis(target, userId) }, userId)
|
||||
return addEdge(Certification(issuerNode, targetNode, userId))
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { Node(issuer)}
|
||||
val targetNode = Node(nodes.getOrPut(Fingerprint(target)) { Node(target, userId) }, userId)
|
||||
return addEdge(Edge(issuerNode, targetNode, userId))
|
||||
}
|
||||
|
||||
fun Network.Builder.buildEdge(issuer: String, target: String, amount: Int, depth: Int): Network.Builder {
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { CertSynopsis(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { CertSynopsis(target) }
|
||||
return addEdge(Edge(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), RegexSet.wildcard()))
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { Node(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { Node(target) }
|
||||
return addEdge(EdgeComponent(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), RegexSet.wildcard()))
|
||||
}
|
||||
|
||||
fun Network.Builder.buildEdge(issuer: String, target: String, amount: Int, depth: Int, regexSet: RegexSet): Network.Builder {
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { CertSynopsis(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { CertSynopsis(target) }
|
||||
return addEdge(Edge(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), regexSet))
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { Node(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { Node(target) }
|
||||
return addEdge(EdgeComponent(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), regexSet))
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reference time of the builder to now.
|
||||
*/
|
||||
fun Network.Builder.now(): Network.Builder {
|
||||
return setReferenceTime(org.pgpainless.wot.network.ReferenceTime.now())
|
||||
return setReferenceTime(ReferenceTime.now())
|
||||
}
|
||||
|
||||
fun Network.getEdgesFor(issuer: Fingerprint, target: Fingerprint): EdgeSet? {
|
||||
return edgeSet[issuer]?.find { it.target.fingerprint == target }
|
||||
fun Network.getEdgesFor(issuer: Fingerprint, target: Fingerprint): Edge? {
|
||||
return edges[issuer]?.find { it.target.fingerprint == target }
|
||||
}
|
||||
|
||||
fun Network.getEdgesFor(issuer: String, target: String): EdgeSet? {
|
||||
fun Network.getEdgesFor(issuer: String, target: String): Edge? {
|
||||
return getEdgesFor(Fingerprint(issuer), Fingerprint(target))
|
||||
}
|
||||
|
||||
fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint): List<Edge>? {
|
||||
fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint): List<EdgeComponent>? {
|
||||
return getEdgeFor(issuer, target, null)
|
||||
}
|
||||
|
||||
fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint, userId: String?): List<Edge>? {
|
||||
return getEdgesFor(issuer, target)?.certifications?.get(userId)
|
||||
fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint, userId: String?): List<EdgeComponent>? {
|
||||
return getEdgesFor(issuer, target)?.components?.get(userId)
|
||||
}
|
||||
|
||||
fun Network.getEdgeFor(issuer: String, target: String): List<Edge>? {
|
||||
fun Network.getEdgeFor(issuer: String, target: String): List<EdgeComponent>? {
|
||||
return getEdgeFor(issuer, target, null)
|
||||
}
|
||||
|
||||
fun Network.getEdgeFor(issuer: String, target: String, userId: String?): List<Edge>? {
|
||||
fun Network.getEdgeFor(issuer: String, target: String, userId: String?): List<EdgeComponent>? {
|
||||
return getEdgeFor(Fingerprint(issuer), Fingerprint(target), userId)
|
||||
}
|
||||
|
|
@ -2,13 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.wot.network.Fingerprint
|
||||
import org.pgpainless.wot.network.Network.Companion.empty
|
||||
import org.pgpainless.wot.network.ReferenceTime.Companion.now
|
||||
import org.pgpainless.wot.network.RegexSet
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
@ -19,8 +17,8 @@ class NetworkTest: NetworkDSL {
|
|||
val referenceTime = now()
|
||||
val network = empty(referenceTime)
|
||||
assert(network.nodes.isEmpty())
|
||||
assert(network.edgeSet.isEmpty())
|
||||
assert(network.reverseEdgeSet.isEmpty())
|
||||
assert(network.edges.isEmpty())
|
||||
assert(network.reverseEdges.isEmpty())
|
||||
assertEquals(referenceTime, network.referenceTime)
|
||||
assertEquals(0, network.numberOfEdges)
|
||||
assertEquals(0, network.numberOfSignatures)
|
||||
|
@ -57,7 +55,7 @@ class NetworkTest: NetworkDSL {
|
|||
buildEdge("A", "C", "Charlie <charlie@example.org>")
|
||||
}
|
||||
|
||||
assertEquals("Network with 3 nodes, 2 edgeSet:\n" +
|
||||
assertEquals("Network with 3 nodes, 2 edges:\n" +
|
||||
"A certifies binding: null <-> B [120]\n" +
|
||||
"A certifies binding: Charlie <charlie@example.org> <-> C [120]\n",
|
||||
network.toString())
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
@ -11,19 +11,19 @@ class NodeTest: NetworkDSL {
|
|||
|
||||
@Test
|
||||
fun `Fingerprint 'A' toString`() {
|
||||
val node = CertSynopsis("A")
|
||||
val node = Node("A")
|
||||
assertEquals("A", node.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Fingerprint 'a' toString`() {
|
||||
val node = CertSynopsis("a")
|
||||
val node = Node("a")
|
||||
assertEquals("A", node.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Fingerprint 'A' and UserID toString`() {
|
||||
val node = CertSynopsis("A", "Alice <alice@example.org>")
|
||||
val node = Node("A", "Alice <alice@example.org>")
|
||||
assertEquals("A (Alice <alice@example.org>)", node.toString())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.wot.network.NetworkDSL
|
||||
import org.pgpainless.wot.network.RegexSet
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
@ -10,6 +11,26 @@ class RegexSetTest: NetworkDSL {
|
|||
private val exampleComRegex = "<[^>]+[@.]example\\.com>\$"
|
||||
private val pgpainlessOrgRegex = "<[^>]+[@.]pgpainless\\.org>\$"
|
||||
|
||||
|
||||
@Test
|
||||
fun simpleMatch() {
|
||||
val stringList: List<String> = listOf("<[^>]+[@.]foobank\\.com>$")
|
||||
val rs = RegexSet.fromExpressionList(stringList);
|
||||
|
||||
assert(rs.matches("Foo Bank Employee <employee@foobank.com>"))
|
||||
assert(rs.matches("<employee@foobank.com>"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun simpleNonMatch() {
|
||||
val stringList: List<String> = listOf("<[^>]+[@.]foobank\\.com>$")
|
||||
val rs = RegexSet.fromExpressionList(stringList);
|
||||
|
||||
assert(!rs.matches("Bar Bank Employee <employee@barbank.com>"))
|
||||
assert(!rs.matches("<employee@barbank.com>"))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `verify that the wildcard RegexSet matches anything`() {
|
||||
val wildcard = RegexSet.wildcard()
|
|
@ -1,4 +1,4 @@
|
|||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.network
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.wot.network.ReferenceTime
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.query
|
||||
|
||||
import org.pgpainless.wot.query.Cost
|
||||
import kotlin.test.Test
|
|
@ -1,28 +1,29 @@
|
|||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.query
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pgpainless.wot.network.Depth
|
||||
import org.pgpainless.wot.network.Path
|
||||
import org.pgpainless.wot.network.NetworkDSL
|
||||
import org.pgpainless.wot.query.Path
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class PathTest: NetworkDSL {
|
||||
|
||||
private val root = CertSynopsis("aabbccddeeAABBCCDDEEaabbccddeeAABBCCDDEE")
|
||||
private val alice = CertSynopsis("0000000000000000000000000000000000000000")
|
||||
private val bob = CertSynopsis("1111111111111111111111111111111111111111")
|
||||
private val root = Node("aabbccddeeAABBCCDDEEaabbccddeeAABBCCDDEE")
|
||||
private val alice = Node("0000000000000000000000000000000000000000")
|
||||
private val bob = Node("1111111111111111111111111111111111111111")
|
||||
|
||||
// Root -(255, 255)-> Alice
|
||||
private val root_alice__fully_trusted = Certification(root, alice, 255, Depth.unconstrained())
|
||||
private val root_alice__fully_trusted = Edge(root, alice, 255, Depth.unconstrained())
|
||||
// Root -(60,0)-> Alice
|
||||
private val root_alice__marginally_trusted = Certification(root, alice, 60, Depth.limited(0))
|
||||
private val root_alice__marginally_trusted = Edge(root, alice, 60, Depth.limited(0))
|
||||
// Alice -(255,255)-> Root
|
||||
private val alice_root = Certification(alice, root, 255, Depth.unconstrained())
|
||||
private val alice_root = Edge(alice, root, 255, Depth.unconstrained())
|
||||
// Alice -(120, 1)-> Bob
|
||||
private val alice_bob = Certification(alice, bob)
|
||||
private val alice_bob = Edge(alice, bob)
|
||||
// Root -> Root
|
||||
private val root_root = Certification(root, root, 120, Depth.limited(1))
|
||||
private val root_root = Edge(root, root, 120, Depth.limited(1))
|
||||
|
||||
@Test
|
||||
fun `verify that an empty Path is properly initialized`() {
|
|
@ -1,19 +1,18 @@
|
|||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.query
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pgpainless.wot.network.Depth
|
||||
import org.pgpainless.wot.network.Path
|
||||
import org.pgpainless.wot.network.Paths
|
||||
import org.pgpainless.wot.network.NetworkDSL
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class PathsTest: NetworkDSL {
|
||||
|
||||
private val alice = CertSynopsis("0000000000000000000000000000000000000000")
|
||||
private val bob = CertSynopsis("1111111111111111111111111111111111111111")
|
||||
private val alice = Node("0000000000000000000000000000000000000000")
|
||||
private val bob = Node("1111111111111111111111111111111111111111")
|
||||
|
||||
private val alice_bob_1 = Certification(alice, bob, 140, Depth.unconstrained())
|
||||
private val alice_bob_2 = Certification(alice, bob, 160, Depth.limited(1))
|
||||
private val alice_bob_1 = Edge(alice, bob, 140, Depth.unconstrained())
|
||||
private val alice_bob_2 = Edge(alice, bob, 160, Depth.limited(1))
|
||||
|
||||
@Test
|
||||
fun `verify that an empty Paths object has an amount of zero`() {
|
|
@ -1,6 +1,5 @@
|
|||
package org.pgpainless.wot.dijkstra
|
||||
package org.pgpainless.wot.query
|
||||
|
||||
import org.pgpainless.wot.query.PairPriorityQueue
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
Loading…
Reference in a new issue