From 3c4088a89e2b52656d84fe784032670e77b009c0 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Sun, 9 Jul 2023 11:05:09 +0200 Subject: [PATCH] Refactor - Renaming CertSynopsis = Node Certification = Edge CertificationSet = EdgeSet --- .../cli/subcommands/AuthenticateCmdTest.kt | 8 +- .../kotlin/org/pgpainless/wot/WebOfTrust.kt | 12 +- .../wot/util/CertificationFactory.kt | 24 ++-- .../test/kotlin/org/pgpainless/wot/PGPDSL.kt | 10 +- .../org/pgpainless/wot/WebOfTrustTest.kt | 18 +-- .../org/pgpainless/wot/WebOfTrustUnitTest.kt | 4 +- .../kotlin/org/pgpainless/wot/api/WoTAPI.kt | 2 +- .../org/pgpainless/wot/dijkstra/Query.kt | 34 +++--- .../dijkstra/filter/CapCertificateFilter.kt | 4 +- .../dijkstra/filter/CertificationFilter.kt | 4 +- .../wot/dijkstra/filter/ChainFilter.kt | 4 +- .../filter/SuppressCertificationFilter.kt | 4 +- .../dijkstra/filter/SuppressIssuerFilter.kt | 4 +- .../filter/TrustedIntroducerFilter.kt | 4 +- .../wot/dijkstra/sq/CertificationSet.kt | 115 ------------------ .../dijkstra/sq/{Certification.kt => Edge.kt} | 32 ++--- .../org/pgpainless/wot/dijkstra/sq/EdgeSet.kt | 115 ++++++++++++++++++ .../org/pgpainless/wot/dijkstra/sq/Network.kt | 56 ++++----- .../dijkstra/sq/{CertSynopsis.kt => Node.kt} | 4 +- .../org/pgpainless/wot/dijkstra/sq/Path.kt | 48 ++++---- ...CertificationSetTest.kt => EdgeSetTest.kt} | 50 ++++---- .../{CertificationTest.kt => EdgeTest.kt} | 20 +-- .../org/pgpainless/wot/dijkstra/NetworkDSL.kt | 60 ++++----- .../pgpainless/wot/dijkstra/NetworkTest.kt | 6 +- .../{CertSynopsisTest.kt => NodeTest.kt} | 2 +- 25 files changed, 322 insertions(+), 322 deletions(-) delete mode 100644 wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/CertificationSet.kt rename wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/{Certification.kt => Edge.kt} (66%) create mode 100644 wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/EdgeSet.kt rename wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/{CertSynopsis.kt => Node.kt} (89%) rename wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/{CertificationSetTest.kt => EdgeSetTest.kt} (65%) rename wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/{CertificationTest.kt => EdgeTest.kt} (70%) rename wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/{CertSynopsisTest.kt => NodeTest.kt} (94%) diff --git a/pgpainless-wot-cli/src/test/kotlin/org/pgpainless/wot/cli/subcommands/AuthenticateCmdTest.kt b/pgpainless-wot-cli/src/test/kotlin/org/pgpainless/wot/cli/subcommands/AuthenticateCmdTest.kt index e1e4072c..d1c1b905 100644 --- a/pgpainless-wot-cli/src/test/kotlin/org/pgpainless/wot/cli/subcommands/AuthenticateCmdTest.kt +++ b/pgpainless-wot-cli/src/test/kotlin/org/pgpainless/wot/cli/subcommands/AuthenticateCmdTest.kt @@ -13,7 +13,7 @@ class AuthenticateCmdTest { val dateFormat = SimpleDateFormat("yyyy-MM-dd") val cmd = AuthenticateCmd() val paths = Paths() - val neal = CertSynopsis( + val neal = Node( Fingerprint("F7173B3C7C685CD9ECC4191B74E445BA0E15C957"), null, RevocationState.notRevoked(), @@ -21,7 +21,7 @@ class AuthenticateCmdTest { Pair("Neal H. Walfield (Code Signing Key) ", RevocationState.notRevoked()) ) ) - val justus = CertSynopsis( + val justus = Node( Fingerprint("CBCD8F030588653EEDD7E2659B7DD433F254904A"), null, RevocationState.notRevoked(), @@ -29,7 +29,7 @@ class AuthenticateCmdTest { Pair("Justus Winter ", RevocationState.notRevoked()) ) ) - val certification = Certification( + val edge = Edge( neal, justus, "Justus Winter ", @@ -39,7 +39,7 @@ class AuthenticateCmdTest { 120, Depth.limited(0), RegexSet.wildcard()) - paths.add(Path(neal, mutableListOf(certification), Depth.auto(0)), 120) + paths.add(Path(neal, mutableListOf(edge), Depth.auto(0)), 120) val testResult = AuthenticateAPI.Result( Fingerprint("CBCD8F030588653EEDD7E2659B7DD433F254904A"), "Justus Winter ", diff --git a/pgpainless-wot/src/main/kotlin/org/pgpainless/wot/WebOfTrust.kt b/pgpainless-wot/src/main/kotlin/org/pgpainless/wot/WebOfTrust.kt index 48905f54..e4eb3f6e 100644 --- a/pgpainless-wot/src/main/kotlin/org/pgpainless/wot/WebOfTrust.kt +++ b/pgpainless-wot/src/main/kotlin/org/pgpainless/wot/WebOfTrust.kt @@ -95,7 +95,7 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) { private val byKeyId: MutableMap> = HashMap() // nodes keyed by fingerprint - private val nodeMap: MutableMap = HashMap() + private val nodeMap: MutableMap = HashMap() init { validatedCertificates.forEach { indexAsNode(it) } @@ -131,7 +131,7 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) { // map user-ids to revocation states val userIds = cert.userIds.associateWith { RevocationState(cert.getUserIdRevocation(it)) } - val node = CertSynopsis(certFingerprint, + val node = Node(certFingerprint, expirationDate, RevocationState(cert.revocationSelfSignature), userIds) @@ -141,7 +141,7 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) { } /** - * Add all verifiable certifications on the certificate as incoming edges to + * Add all verifiable certifications on the certificate as incoming edgeSet to * the [Network.Builder]. * * @param validatedTarget validated certificate @@ -158,7 +158,7 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) { processDelegation(targetPrimaryKey, target, delegation) } - // Certification Signatures by X on Y over user-ID U + // Edge Signatures by X on Y over user-ID U val userIds = targetPrimaryKey.userIDs while (userIds.hasNext()) { val userId = userIds.next() @@ -180,7 +180,7 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) { * @param delegation delegation signature */ private fun processDelegation(targetPrimaryKey: PGPPublicKey, - target: CertSynopsis, + target: Node, delegation: PGPSignature) { // There might be more than one cert with a subkey of matching key-id val issuerCandidates = byKeyId[delegation.keyID] @@ -217,7 +217,7 @@ class WebOfTrust(private val certificateStore: PGPCertificateStore) { * @param certification certification signature */ private fun processCertificationOnUserId(targetPrimaryKey: PGPPublicKey, - target: CertSynopsis, + target: Node, userId: String, certification: PGPSignature) { // There might be more than one cert with a subkey of matching key-id diff --git a/pgpainless-wot/src/main/kotlin/org/pgpainless/wot/util/CertificationFactory.kt b/pgpainless-wot/src/main/kotlin/org/pgpainless/wot/util/CertificationFactory.kt index 944f95c4..6ad05b0c 100644 --- a/pgpainless-wot/src/main/kotlin/org/pgpainless/wot/util/CertificationFactory.kt +++ b/pgpainless-wot/src/main/kotlin/org/pgpainless/wot/util/CertificationFactory.kt @@ -6,8 +6,8 @@ package org.pgpainless.wot.util import org.bouncycastle.openpgp.PGPSignature import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil -import org.pgpainless.wot.dijkstra.sq.CertSynopsis -import org.pgpainless.wot.dijkstra.sq.Certification +import org.pgpainless.wot.dijkstra.sq.Node +import org.pgpainless.wot.dijkstra.sq.Edge import org.pgpainless.wot.dijkstra.sq.Depth import org.pgpainless.wot.dijkstra.sq.RegexSet import org.pgpainless.wot.dijkstra.sq.RegexSet.Companion.fromExpressionList @@ -16,26 +16,26 @@ class CertificationFactory { companion object { @JvmStatic - fun fromDelegation(issuer: CertSynopsis, - target: CertSynopsis, - signature: PGPSignature): Certification { + fun fromDelegation(issuer: Node, + target: Node, + signature: PGPSignature): Edge { return fromSignature(issuer, target, null, signature) } @JvmStatic - fun fromCertification(issuer: CertSynopsis, - target: CertSynopsis, + fun fromCertification(issuer: Node, + target: Node, targetUserId: String, - signature: PGPSignature): Certification { + signature: PGPSignature): Edge { return fromSignature(issuer, target, targetUserId, signature) } @JvmStatic - fun fromSignature(issuer: CertSynopsis, - target: CertSynopsis, + fun fromSignature(issuer: Node, + target: Node, targetUserId: String?, - signature: PGPSignature): Certification { - return Certification( + signature: PGPSignature): Edge { + return Edge( issuer, target, targetUserId, diff --git a/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/PGPDSL.kt b/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/PGPDSL.kt index d25f59a9..73547ef6 100644 --- a/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/PGPDSL.kt +++ b/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/PGPDSL.kt @@ -5,18 +5,18 @@ import org.bouncycastle.openpgp.PGPSignature import org.pgpainless.algorithm.RevocationStateType import org.pgpainless.key.OpenPgpFingerprint import org.pgpainless.key.info.KeyRingInfo -import org.pgpainless.wot.dijkstra.sq.CertSynopsis +import org.pgpainless.wot.dijkstra.sq.Node import org.pgpainless.wot.dijkstra.sq.Fingerprint import org.pgpainless.wot.dijkstra.sq.RevocationState interface PGPDSL { - fun CertSynopsis(certificate: PGPPublicKeyRing): CertSynopsis { - return CertSynopsis(Fingerprint(certificate), ) + fun CertSynopsis(certificate: PGPPublicKeyRing): Node { + return Node(Fingerprint(certificate), ) } - fun CertSynopsis(validatedCert: KeyRingInfo): CertSynopsis { - return CertSynopsis( + fun CertSynopsis(validatedCert: KeyRingInfo): Node { + return Node( Fingerprint(validatedCert.fingerprint), validatedCert.primaryKeyExpirationDate, RevocationState(validatedCert.revocationState), diff --git a/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustTest.kt b/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustTest.kt index b2917dfd..b7747515 100644 --- a/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustTest.kt +++ b/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustTest.kt @@ -7,7 +7,7 @@ package org.pgpainless.wot import org.bouncycastle.openpgp.PGPPublicKeyRing import org.pgpainless.key.OpenPgpFingerprint -import org.pgpainless.wot.dijkstra.sq.CertificationSet +import org.pgpainless.wot.dijkstra.sq.EdgeSet import org.pgpainless.wot.dijkstra.sq.Fingerprint import org.pgpainless.wot.dijkstra.sq.Network import org.pgpainless.wot.testfixtures.TestCertificateStores @@ -55,7 +55,7 @@ class WebOfTrustTest { } } - val fooBankCaEdges = network.edges[fooBankCa]!! + val fooBankCaEdges = network.edgeSet[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.edges.isEmpty() } - assertTrue { network.reverseEdges.isEmpty() } + assertTrue { network.edgeSet.isEmpty() } + assertTrue { network.reverseEdgeSet.isEmpty() } } @Test @@ -94,7 +94,7 @@ class WebOfTrustTest { private fun assertHasIssuerAndTarget( - certifications: CertificationSet, + certifications: EdgeSet, 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): CertificationSet? { - val edges = network.edges[issuer] ?: return null + private fun getEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): EdgeSet? { + val edges = network.edgeSet[issuer] ?: return null return edges.find { target == it.target.fingerprint } } - private fun getReverseEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): CertificationSet? { - val revEdges = network.reverseEdges[target] ?: return null + private fun getReverseEdgeFromTo(network: Network, issuer: Fingerprint, target: Fingerprint): EdgeSet? { + val revEdges = network.reverseEdgeSet[target] ?: return null return revEdges.find { issuer == it.issuer.fingerprint } } } \ No newline at end of file diff --git a/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustUnitTest.kt b/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustUnitTest.kt index 2a9813cf..20a12ad6 100644 --- a/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustUnitTest.kt +++ b/pgpainless-wot/src/test/kotlin/org/pgpainless/wot/WebOfTrustUnitTest.kt @@ -51,7 +51,7 @@ class WebOfTrustUnitTest { @Test fun simple() { val network = getNetwork("/home/heiko/src/sequoia-wot/tests/data/simple.pgp") - println("Network contains " + network.nodes.size + " nodes with " + network.numberOfEdges + " edges built from " + network.numberOfSignatures + " signatures.") + println("Network contains " + network.nodes.size + " nodes with " + network.numberOfEdges + " edgeSet built from " + network.numberOfSignatures + " signatures.") // -- @@ -162,7 +162,7 @@ class WebOfTrustUnitTest { // Certified by: 78C3814EFD16E68F4F1AB4B874E30AE11FFCFB1B val network = getNetwork("/home/heiko/src/sequoia-wot/tests/data/cycle.pgp") - println("Network contains " + network.nodes.size + " nodes with " + network.numberOfEdges + " edges built from " + network.numberOfSignatures + " signatures.") + println("Network contains " + network.nodes.size + " nodes with " + network.numberOfEdges + " edgeSet built from " + network.numberOfSignatures + " signatures.") val q = Query(network, Roots(), false) val a1 = q.backwardPropagate(frankFpr, frankUid, false, IdempotentCertificationFilter()); diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/api/WoTAPI.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/api/WoTAPI.kt index ce778c32..c5691702 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/api/WoTAPI.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/api/WoTAPI.kt @@ -11,7 +11,7 @@ import org.pgpainless.wot.dijkstra.sq.ReferenceTime /** * Web of Trust API, offering different operations. * - * @param network initialized [Network] containing certificates as nodes and certifications as edges. + * @param network initialized [Network] containing certificates as nodes and certifications as edgeSet. * @param trustRoots one or more [Fingerprints][Fingerprint] of trust-roots. * @param gossip if true, consider all certificates as weakly trusted trust-roots * @param certificationNetwork if true, all certifications are treated as delegations with infinite trust depth and no regular expressions diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/Query.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/Query.kt index 0246c6bf..a2657131 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/Query.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/Query.kt @@ -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: Certification? + val next: Edge? ) class Query( @@ -174,7 +174,7 @@ class Query( /// /// # Algorithm /// - /// This algorithm reverses the edges in the network and then + /// This algorithm reverses the edgeSet 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: Certification = fp.next!! // FIXME + val c: Edge = fp.next!! // FIXME val a = c.trustAmount val d = c.trustDepth @@ -430,10 +430,10 @@ class Query( // Get signeeFp // Not limiting by required_depth, because 'network' doesn't expose an interface for this - val certificationSets: List = - network.reverseEdges[signeeFpr].orEmpty() // "certifications_of" + val edges: List = + network.reverseEdgeSet[signeeFpr].orEmpty() // "certifications_of" - if (certificationSets.isEmpty()) { + if (edges.isEmpty()) { // Nothing certified it. The path is a dead end. logger.debug("{} was not certified, dead end", signeeFpr) continue; @@ -442,9 +442,9 @@ class Query( logger.debug("Visiting {} ({}), certified {} times", signee.fingerprint, signee.toString(), - certificationSets.size) + edges.size) - for (certification in certificationSets + for (certification in edges .map { cs -> cs.certifications .map { it.value }.flatten() @@ -472,7 +472,7 @@ class Query( if (fv.amount == 0) { - logger.debug(" Certification amount is 0, skipping") + logger.debug(" Edge amount is 0, skipping") continue; } @@ -481,20 +481,20 @@ class Query( && certification.userId != targetUserid) { assert(signeeFp.next == null) - logger.debug(" Certification certifies target, but for the wrong user id (want: {}, got: {})", + logger.debug(" Edge certifies target, but for the wrong user id (want: {}, got: {})", targetUserid, certification.userId) continue; } if (fv.depth < Depth.auto(signeeFpCost.depth)) { - logger.debug(" Certification does not have enough depth ({}, needed: {}), skipping", fv.depth, signeeFpCost.depth) + logger.debug(" Edge does not have enough depth ({}, needed: {}), skipping", fv.depth, signeeFpCost.depth) continue; } val re = fv.regexps if ((re != null) && !re.matches(targetUserid)) { - logger.debug(" Certification's re does not match target User ID, skipping.") + logger.debug(" Edge'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 - // edges) as this allows us to reach more of + // edgeSet) 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 = Certification( + val selfsig = Edge( 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 = mutableListOf(); + val nodes: MutableList = 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 = Certification(target, target, targetUserid, Date()); + val selfsig = Edge(target, target, targetUserid, Date()); nodes.add(selfsig); } } @@ -725,7 +725,7 @@ class Query( // .unwrap_or("".into()); // t!(" <{}, {}>: {}", // fpr, userid, - // format!("{} trust amount (max: {}), {} edges", + // format!("{} trust amount (max: {}), {} edgeSet", // amount, path.amount(), // path.len() - 1)); // } diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/CapCertificateFilter.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/CapCertificateFilter.kt index 2066cc47..b4406da3 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/CapCertificateFilter.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/CapCertificateFilter.kt @@ -4,7 +4,7 @@ package org.pgpainless.wot.dijkstra.filter -import org.pgpainless.wot.dijkstra.sq.Certification +import org.pgpainless.wot.dijkstra.sq.Edge import org.pgpainless.wot.dijkstra.sq.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 = hashMapOf() - override fun cost(c: Certification, values: FilterValues, ignoreRegexps: Boolean): Boolean { + override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean { caps[c.issuer.fingerprint]?.let { if (it < values.amount) { values.amount = it diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/CertificationFilter.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/CertificationFilter.kt index 8fd4a1fb..dffcd1ee 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/CertificationFilter.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/CertificationFilter.kt @@ -4,7 +4,7 @@ package org.pgpainless.wot.dijkstra.filter -import org.pgpainless.wot.dijkstra.sq.Certification +import org.pgpainless.wot.dijkstra.sq.Edge import org.pgpainless.wot.dijkstra.sq.Depth import org.pgpainless.wot.dijkstra.sq.RegexSet @@ -33,7 +33,7 @@ interface CertificationFilter { * * If the function returns `false`, the certification should be skipped. */ - fun cost(c: Certification, values: FilterValues, ignoreRegexps: Boolean): Boolean { + fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean { return true } diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/ChainFilter.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/ChainFilter.kt index f48dcaed..9e9eed9f 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/ChainFilter.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/ChainFilter.kt @@ -4,7 +4,7 @@ package org.pgpainless.wot.dijkstra.filter -import org.pgpainless.wot.dijkstra.sq.Certification +import org.pgpainless.wot.dijkstra.sq.Edge /** * A filter that chains multiple filters together. @@ -15,7 +15,7 @@ import org.pgpainless.wot.dijkstra.sq.Certification */ class ChainFilter(val filters: MutableList) : CertificationFilter { - override fun cost(c: Certification, values: FilterValues, ignoreRegexps: Boolean): Boolean { + override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean { // If any inner filter returns `false`, immediately return false return !this.filters.any { !it.cost(c, values, ignoreRegexps) } diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/SuppressCertificationFilter.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/SuppressCertificationFilter.kt index e1080b80..08a48d9e 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/SuppressCertificationFilter.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/SuppressCertificationFilter.kt @@ -4,7 +4,7 @@ package org.pgpainless.wot.dijkstra.filter -import org.pgpainless.wot.dijkstra.sq.Certification +import org.pgpainless.wot.dijkstra.sq.Edge import org.pgpainless.wot.dijkstra.sq.Fingerprint import org.pgpainless.wot.dijkstra.sq.Path @@ -12,7 +12,7 @@ class SuppressCertificationFilter() : CertificationFilter { // A certification's trust amount will be suppressed by this amount. private val amount: HashMap, Int> = hashMapOf() - override fun cost(c: Certification, values: FilterValues, ignoreRegexps: Boolean): Boolean { + override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean { amount[Pair(c.issuer.fingerprint, c.issuer.fingerprint)]?.let { suppress -> values.amount = if (values.amount > suppress) { values.amount - suppress diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/SuppressIssuerFilter.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/SuppressIssuerFilter.kt index f699c4a5..13c01fb1 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/SuppressIssuerFilter.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/SuppressIssuerFilter.kt @@ -4,7 +4,7 @@ package org.pgpainless.wot.dijkstra.filter -import org.pgpainless.wot.dijkstra.sq.Certification +import org.pgpainless.wot.dijkstra.sq.Edge import org.pgpainless.wot.dijkstra.sq.Fingerprint /** @@ -14,7 +14,7 @@ class SuppressIssuerFilter() : CertificationFilter { // A certification's trust amount will be suppressed by this amount. private val amount: HashMap = hashMapOf() - override fun cost(c: Certification, values: FilterValues, ignoreRegexps: Boolean): Boolean { + override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean { amount[c.issuer.fingerprint]?.let { suppress -> values.amount = if (values.amount > suppress) { values.amount - suppress diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/TrustedIntroducerFilter.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/TrustedIntroducerFilter.kt index 23ab6e5c..b3be1d11 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/TrustedIntroducerFilter.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/filter/TrustedIntroducerFilter.kt @@ -4,7 +4,7 @@ package org.pgpainless.wot.dijkstra.filter -import org.pgpainless.wot.dijkstra.sq.Certification +import org.pgpainless.wot.dijkstra.sq.Edge import org.pgpainless.wot.dijkstra.sq.Depth /** @@ -16,7 +16,7 @@ import org.pgpainless.wot.dijkstra.sq.Depth * This filter can be used to view a network as a 'certification network'. */ class TrustedIntroducerFilter : CertificationFilter { - override fun cost(c: Certification, values: FilterValues, ignoreRegexps: Boolean): Boolean { + override fun cost(c: Edge, values: FilterValues, ignoreRegexps: Boolean): Boolean { values.depth = Depth.unconstrained() if (!ignoreRegexps) { values.regexps = null diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/CertificationSet.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/CertificationSet.kt deleted file mode 100644 index 47c55b6a..00000000 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/CertificationSet.kt +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.wot.dijkstra.sq - -/** - * A [CertificationSet] is a set of [Certifications][Certification] made by the same issuer, on the same - * target certificate. - * In some sense, a [CertificationSet] can be considered an edge in the web of trust. - * - * @param issuer synopsis of the certificate that issued the [Certifications][Certification] - * @param target synopsis of the certificate that is targeted by the [Certifications][Certification] - * @param certifications [Map] keyed by user-ids, whose values are [Lists][List] of - * [Certifications][Certification] that are calculated over the key user-id. Note, that the key can also be null for - * [Certifications][Certification] over the targets primary key. - */ -class CertificationSet( - val issuer: CertSynopsis, - val target: CertSynopsis, - certifications: Map>) { - - init { - certifications.forEach { (_, certifications) -> - certifications.forEach { - add(it) - } - } - } - - private val _certifications: MutableMap> = mutableMapOf() - val certifications: Map> - get() = _certifications.toMutableMap() - - companion object { - - /** - * Create an empty [CertificationSet]. - * - * @param issuer the certificate that issued the [Certifications][Certification]. - * @param target the certificate that is targeted by the [Certifications][Certification]. - */ - @JvmStatic - fun empty(issuer: CertSynopsis, target: CertSynopsis): CertificationSet { - return CertificationSet(issuer, target, HashMap()) - } - - /** - * Create a [CertificationSet] from a single [Certification]. - * - * @param certification certification - */ - @JvmStatic - fun fromCertification(certification: Certification): CertificationSet { - val set = empty(certification.issuer, certification.target) - set.add(certification) - return set - } - } - - /** - * Merge the given [CertificationSet] into this. - * This method copies all [Certifications][Certification] from the other [CertificationSet] into [certifications]. - * - * @param other [CertificationSet] with the same issuer fingerprint and target fingerprint as this object. - */ - fun merge(other: CertificationSet) { - 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 [Certification] into this objects [certifications]. - * Adding multiple [Certifications][Certification] for the same datum, but with different creation times results in - * only the most recent [Certification(s)][Certification] to be preserved. - * - * @param certification [Certification] with the same issuer fingerprint and target fingerprint as this object. - */ - fun add(certification: Certification) { - require(issuer.fingerprint == certification.issuer.fingerprint) { "Issuer fingerprint mismatch." } - require(target.fingerprint == certification.target.fingerprint) { "Target fingerprint mismatch." } - - val certificationsForUserId = _certifications.getOrPut(certification.userId) { mutableListOf() } - if (certificationsForUserId.isEmpty()) { - certificationsForUserId.add(certification) - return - } - - val existing = certificationsForUserId[0] - // if existing is older than this certification - if (existing.creationTime.before(certification.creationTime)) { - // throw away older certifications - certificationsForUserId.clear() - } - // If this certification is newest (or equally old!) - if (!existing.creationTime.after(certification.creationTime)) { - certificationsForUserId.add(certification) - } - // else this certification is older, so don't add it - } - - override fun toString(): String { - return certifications.map { it.value }.flatten().joinToString("\n") - } -} \ No newline at end of file diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Certification.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Edge.kt similarity index 66% rename from wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Certification.kt rename to wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Edge.kt index 259ab703..7e1a1f53 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Certification.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Edge.kt @@ -7,22 +7,22 @@ package org.pgpainless.wot.dijkstra.sq import java.util.* /** - * A [Certification] is a signature issued by one certificate over a datum on another target certificate. + * 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. * - * @param issuer synopsis of the certificate that issued the [Certification] - * @param target synopsis of the certificate that is target of this [Certification] - * @param userId optional user-id. If this is null, the [Certification] is made over the primary key of the target. - * @param creationTime creation time of the [Certification] - * @param expirationTime optional expiration time of the [Certification] + * @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 */ -data class Certification( - val issuer: CertSynopsis, - val target: CertSynopsis, +data class Edge( + val issuer: Node, + val target: Node, val userId: String?, val creationTime: Date, val expirationTime: Date?, @@ -33,17 +33,17 @@ data class Certification( ) { /** - * Construct a [Certification] with default values. The result is non-expiring, will be exportable and has a + * 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 [Certification] - * @param target synopsis of the certificate that is target of this [Certification] - * @param targetUserId optional user-id. If this is null, the [Certification] is made over the primary key of the target. - * @param creationTime creation time of the [Certification] + * @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: CertSynopsis, - target: CertSynopsis, + issuer: Node, + target: Node, targetUserId: String? = null, creationTime: Date) : this(issuer, target, targetUserId, creationTime, null, true, 120, Depth.limited(0), RegexSet.wildcard()) diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/EdgeSet.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/EdgeSet.kt new file mode 100644 index 00000000..2223a14f --- /dev/null +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/EdgeSet.kt @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: 2023 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.wot.dijkstra.sq + +/** + * 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>) { + + init { + certifications.forEach { (_, certifications) -> + certifications.forEach { + add(it) + } + } + } + + private val _certifications: MutableMap> = mutableMapOf() + val certifications: Map> + 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") + } +} \ No newline at end of file diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Network.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Network.kt index 284b24b9..b050d530 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Network.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Network.kt @@ -5,20 +5,20 @@ package org.pgpainless.wot.dijkstra.sq /** - * A network consists of nodes, and edges between them. - * For the Web of Trust, nodes consist of [CertSynopses][CertSynopsis], while the edges between the nodes are - * [CertificationSets][CertificationSet]. + * 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]. * * @constructor creates a new network - * @param nodes contains a [Map] of [CertSynopsis] keyed by their [Fingerprint] - * @param edges [Map] keyed by the [fingerprint][Fingerprint] of an issuer, whose values are [Lists][List] containing all edges originating from the issuer. - * @param reverseEdges [Map] keyed by the [fingerprint][Fingerprint] of a target, whose values are [Lists][List] containing all edges pointing to the target + * @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 referenceTime reference time at which the [Network] was built */ class Network( - val nodes: Map, - val edges: Map>, - val reverseEdges: Map>, + val nodes: Map, + val edgeSet: Map>, + val reverseEdgeSet: Map>, val referenceTime: ReferenceTime) { companion object { @@ -34,13 +34,13 @@ class Network( } /** - * The total number of edges on the network. + * The total number of edgeSet on the network. * - * @return number of edges + * @return number of edgeSet */ val numberOfEdges: Int get() { - return edges.values.sumOf { it.size } + return edgeSet.values.sumOf { it.size } } /** @@ -48,7 +48,7 @@ class Network( */ val numberOfSignatures: Int get() { - return edges.values + return edgeSet.values .flatten() .flatMap { it.certifications.values } .sumOf { it.size } @@ -56,9 +56,9 @@ class Network( override fun toString(): String { val sb = StringBuilder() - sb.append("Network with ${nodes.size} nodes, $numberOfEdges edges:\n") + sb.append("Network with ${nodes.size} nodes, $numberOfEdges edgeSet:\n") for (issuer in nodes.keys) { - val outEdges = edges[issuer] ?: continue + val outEdges = edgeSet[issuer] ?: continue for (edge in outEdges) { sb.appendLine(edge) } @@ -67,22 +67,22 @@ class Network( } class Builder internal constructor() { - val nodes: MutableMap = mutableMapOf() - private val protoEdges: MutableMap, CertificationSet> = mutableMapOf() + val nodes: MutableMap = mutableMapOf() + private val protoEdgeSet: MutableMap, EdgeSet> = mutableMapOf() private var referenceTime: ReferenceTime = ReferenceTime.now() - fun addNode(node: CertSynopsis): Builder { + fun addNode(node: Node): Builder { nodes[node.fingerprint] = node return this } - fun getNode(fingerprint: Fingerprint): CertSynopsis? { + fun getNode(fingerprint: Fingerprint): Node? { return nodes[fingerprint] } - fun addEdge(edge: Certification): Builder { - protoEdges.getOrPut(Pair(edge.issuer.fingerprint, edge.target.fingerprint)) { - CertificationSet.empty(edge.issuer, edge.target) + fun addEdge(edge: Edge): Builder { + protoEdgeSet.getOrPut(Pair(edge.issuer.fingerprint, edge.target.fingerprint)) { + EdgeSet.empty(edge.issuer, edge.target) }.add(edge) return this } @@ -93,20 +93,20 @@ class Network( } fun build(): Network { - val edges = mutableMapOf>() - val revEdges = mutableMapOf>() + val edgeSet = mutableMapOf>() + val revEdgeSet = mutableMapOf>() - protoEdges.forEach { (pair, certificationSet) -> - edges.getOrPut(pair.first) { + protoEdgeSet.forEach { (pair, certificationSet) -> + edgeSet.getOrPut(pair.first) { mutableListOf() }.add(certificationSet) - revEdges.getOrPut(pair.second) { + revEdgeSet.getOrPut(pair.second) { mutableListOf() }.add(certificationSet) } - return Network(nodes, edges, revEdges, referenceTime) + return Network(nodes, edgeSet, revEdgeSet, referenceTime) } } } \ No newline at end of file diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/CertSynopsis.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Node.kt similarity index 89% rename from wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/CertSynopsis.kt rename to wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Node.kt index ad3a1614..662ba134 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/CertSynopsis.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Node.kt @@ -7,14 +7,14 @@ package org.pgpainless.wot.dijkstra.sq import java.util.* /** - * A [CertSynopsis] is a proxy object containing information about a certificate. + * A [Node] is a proxy object containing information about a certificate. * * @param fingerprint [Fingerprint] of the certificate * @param expirationTime optional expiration time of the certificate * @param revocationState [RevocationState] denoting whether the certificate is revoked or not * @param userIds [Map] of user-ids on the certificate, along with their revocation states */ -data class CertSynopsis( +data class Node( val fingerprint: Fingerprint, val expirationTime: Date? = null, val revocationState: RevocationState = RevocationState.notRevoked(), diff --git a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Path.kt b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Path.kt index a87b188e..9d71fea0 100644 --- a/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Path.kt +++ b/wot-dijkstra/src/main/kotlin/org/pgpainless/wot/dijkstra/sq/Path.kt @@ -7,33 +7,33 @@ package org.pgpainless.wot.dijkstra.sq import kotlin.math.min /** - * A [Path] comprises a root [CertSynopsis], a list of edges ([Certifications][Certification]), as well as a + * A [Path] comprises a root [Node], a list of edgeSet ([Certifications][Edge]), as well as a * residual depth. * * @param root root of the path - * @param edges list of edges from the root to the target + * @param edges list of edgeSet from the root to the target * @param residualDepth residual depth that is decreased each time another edge is appended */ class Path( - val root: CertSynopsis, - private val edges: MutableList, + val root: Node, + private val edges: MutableList, var residualDepth: Depth ) { /** * Construct a [Path] only consisting of the trust root. - * The [Path] will have an empty list of edges and an unconstrained residual [Depth]. + * The [Path] will have an empty list of edgeSet and an unconstrained residual [Depth]. * * @param root trust root */ - constructor(root: CertSynopsis) : this( - root, mutableListOf(), Depth.unconstrained()) + constructor(root: Node) : this( + root, mutableListOf(), Depth.unconstrained()) /** * Current target of the path. * This corresponds to the target of the last entry in the edge list. */ - val target: CertSynopsis + val target: Node get() { return if (edges.isEmpty()) { root @@ -43,12 +43,12 @@ class Path( } /** - * List of [CertSynopses][CertSynopsis] (nodes) of the path. - * The first entry is the [root]. The other entries are the targets of the edges. + * List of [CertSynopses][Node] (nodes) of the path. + * The first entry is the [root]. The other entries are the targets of the edgeSet. */ - val certificates: List + val certificates: List get() { - val certs: MutableList = mutableListOf(root) + val certs: MutableList = mutableListOf(root) for (certification in edges) { certs.add(certification.target) } @@ -63,9 +63,9 @@ class Path( get() = edges.size + 1 /** - * List of edges. + * List of edgeSet. */ - val certifications: List + val certifications: List get() = edges.toList() /** @@ -88,37 +88,37 @@ 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 [Certification] would result in a cyclic path + * @throws IllegalArgumentException if the addition of the [Edge] would result in a cyclic path */ - fun append(certification: Certification) { - require(target.fingerprint == certification.issuer.fingerprint) { - "Cannot append certification to path: Path's tail is not issuer of the certification." + fun append(aEdge: Edge) { + require(target.fingerprint == aEdge.issuer.fingerprint) { + "Cannot append edge to path: Path's tail is not issuer of the edge." } require(residualDepth.isUnconstrained() || residualDepth.limit!! > 0) { "Not enough depth." } // root is c's target -> illegal cycle - var cyclic = root.fingerprint == certification.target.fingerprint + var cyclic = root.fingerprint == aEdge.target.fingerprint for ((i, edge) in edges.withIndex()) { if (cyclic) { break } // existing edge points to c's target -> illegal cycle - if (edge.target.fingerprint == certification.target.fingerprint) { + if (aEdge.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 - edge.userId == certification.userId + aEdge.userId == edge.userId } } } - require(!cyclic) { "Adding the certification to the path would create a cycle." } + require(!cyclic) { "Adding the edge to the path would create a cycle." } - residualDepth = certification.trustDepth.min(residualDepth.decrease(1)) - edges.add(certification) + residualDepth = aEdge.trustDepth.min(residualDepth.decrease(1)) + edges.add(aEdge) } override fun toString(): String { diff --git a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertificationSetTest.kt b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/EdgeSetTest.kt similarity index 65% rename from wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertificationSetTest.kt rename to wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/EdgeSetTest.kt index 2a14ea67..f81113c1 100644 --- a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertificationSetTest.kt +++ b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/EdgeSetTest.kt @@ -11,20 +11,20 @@ import java.util.* import kotlin.test.assertEquals import kotlin.test.assertTrue -class CertificationSetTest { +class EdgeSetTest { - private val alice = CertSynopsis(Fingerprint("A"), null, RevocationState.notRevoked(), mapOf()) - private val bob = CertSynopsis(Fingerprint("B"), null, RevocationState.notRevoked(), mapOf()) - private val charlie = CertSynopsis(Fingerprint("C"), null, RevocationState.notRevoked(), mapOf()) + 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 = Certification(alice, bob, null, Date()) - private val aliceSignsBobUserId = Certification(alice, bob, "Bob ", Date()) - private val aliceSignsCharlie = Certification(alice, charlie, null, Date()) - private val charlieSignsBob = Certification(charlie, bob, null, Date()) + private val aliceSignsBob = Edge(alice, bob, null, Date()) + private val aliceSignsBobUserId = Edge(alice, bob, "Bob ", Date()) + private val aliceSignsCharlie = Edge(alice, charlie, null, Date()) + private val charlieSignsBob = Edge(charlie, bob, null, Date()) @Test fun `verify that properties of an empty CertificationSet are also empty`() { - val empty = CertificationSet.empty(alice, bob) + val empty = EdgeSet.empty(alice, bob) assert(empty.certifications.isEmpty()) assertEquals(alice, empty.issuer) assertEquals(bob, empty.target) @@ -32,7 +32,7 @@ class CertificationSetTest { @Test fun `verify that add()ing Certification objects works if issuer and target match that of the CertificationSet`() { - val set = CertificationSet.empty(alice, bob) + val set = EdgeSet.empty(alice, bob) set.add(aliceSignsBob) assertTrue { @@ -48,20 +48,20 @@ class CertificationSetTest { @Test fun `verify that add()ing another Certification object fails if the issuer mismatches`() { - val set = CertificationSet.empty(alice, bob) + val set = EdgeSet.empty(alice, bob) assertThrows { set.add(charlieSignsBob) } } @Test fun `verify that add()ing another Certification object fails if the target mismatches`() { - val set = CertificationSet.empty(alice, bob) + val set = EdgeSet.empty(alice, bob) assertThrows { set.add(aliceSignsCharlie) } } @Test fun `verify that merge()ing another CertificationSet works if issuer and target match that of the CertificationSet`() { - val set = CertificationSet.fromCertification(aliceSignsBob) - val others = CertificationSet.fromCertification(aliceSignsBobUserId) + val set = EdgeSet.fromCertification(aliceSignsBob) + val others = EdgeSet.fromCertification(aliceSignsBobUserId) set.merge(others) assertEquals(2, set.certifications.size) @@ -71,23 +71,23 @@ class CertificationSetTest { @Test fun `verify that merge()ing another CertificationSet with mismatched issuer fails`() { - val set = CertificationSet.fromCertification(aliceSignsBob) - val issuerMismatch = CertificationSet.fromCertification(charlieSignsBob) + val set = EdgeSet.fromCertification(aliceSignsBob) + val issuerMismatch = EdgeSet.fromCertification(charlieSignsBob) assertThrows { set.merge(issuerMismatch) } } @Test fun `verify that merge()ing another CertificationSet with mismatched target fails`() { - val set = CertificationSet.fromCertification(aliceSignsBob) - val targetMismatch = CertificationSet.fromCertification(aliceSignsCharlie) + val set = EdgeSet.fromCertification(aliceSignsBob) + val targetMismatch = EdgeSet.fromCertification(aliceSignsCharlie) assertThrows { set.merge(targetMismatch) } } @Test fun `verify that merge()ing a CertificationSet with itself is idempotent`() { - val set = CertificationSet.fromCertification(aliceSignsBob) + val set = EdgeSet.fromCertification(aliceSignsBob) assertEquals(1, set.certifications.size) set.merge(set) assertEquals(1, set.certifications.size) @@ -95,13 +95,13 @@ class CertificationSetTest { @Test fun `verify that toString() of an empty CertificationSet is the empty string`() { - val empty = CertificationSet.empty(alice, bob) + val empty = EdgeSet.empty(alice, bob) assertEquals("", empty.toString()) } @Test fun `verify that toString() of a CertificationSet with two Certifications matches our expectations`() { - val twoCerts = CertificationSet.fromCertification(aliceSignsBob) + val twoCerts = EdgeSet.fromCertification(aliceSignsBob) twoCerts.add(aliceSignsBobUserId) assertEquals("A certifies binding: null <-> B [120]\n" + @@ -112,11 +112,11 @@ class CertificationSetTest { 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 = Certification(alice, bob, "Bob ", fiveSecondsBefore) - val new = Certification(alice, bob, "Bob ", now) - val new2 = Certification(alice, bob, "Bob ", now, null, true, 44, Depth.auto(10), RegexSet.wildcard()) + val old = Edge(alice, bob, "Bob ", fiveSecondsBefore) + val new = Edge(alice, bob, "Bob ", now) + val new2 = Edge(alice, bob, "Bob ", now, null, true, 44, Depth.auto(10), RegexSet.wildcard()) - var set = CertificationSet(alice, bob, mapOf()) + var set = EdgeSet(alice, bob, mapOf()) set.add(old) assertEquals(listOf(old), set.certifications["Bob "]) diff --git a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertificationTest.kt b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/EdgeTest.kt similarity index 70% rename from wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertificationTest.kt rename to wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/EdgeTest.kt index 56be10d9..2e966404 100644 --- a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertificationTest.kt +++ b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/EdgeTest.kt @@ -1,26 +1,26 @@ package org.pgpainless.wot.dijkstra import org.junit.jupiter.api.Test -import org.pgpainless.wot.dijkstra.sq.CertSynopsis -import org.pgpainless.wot.dijkstra.sq.Certification +import org.pgpainless.wot.dijkstra.sq.Node +import org.pgpainless.wot.dijkstra.sq.Edge import org.pgpainless.wot.dijkstra.sq.Fingerprint import org.pgpainless.wot.dijkstra.sq.RevocationState import java.util.* import kotlin.test.assertEquals -class CertificationTest { +class EdgeTest { - private val alice = CertSynopsis( + private val alice = Node( Fingerprint("A"), null, RevocationState.notRevoked(), mapOf(Pair("Alice ", RevocationState.notRevoked()))) - private val bob = CertSynopsis( + private val bob = Node( Fingerprint("B"), null, RevocationState.notRevoked(), mapOf(Pair("Bob ", RevocationState.notRevoked()))) - private val charlie = CertSynopsis( + private val charlie = Node( Fingerprint("C"), null, RevocationState.notRevoked(), @@ -28,21 +28,21 @@ class CertificationTest { @Test fun `verify result of toString() on certification`() { - val certification = Certification(alice, bob, "Bob ", Date()) + val edge = Edge(alice, bob, "Bob ", Date()) assertEquals("A certifies binding: Bob <-> B [120]", - certification.toString()) + edge.toString()) } @Test fun `verify result of toString() on delegation`() { - val delegation = Certification(alice, bob, null, Date()) + val delegation = Edge(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 = Certification(charlie, bob, null, Date()) + val delegation = Edge(charlie, bob, null, Date()) assertEquals("C certifies binding: null <-> B [120]", delegation.toString()) } diff --git a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NetworkDSL.kt b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NetworkDSL.kt index 4b36bc35..d6096ad8 100644 --- a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NetworkDSL.kt +++ b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NetworkDSL.kt @@ -13,52 +13,52 @@ import java.util.* interface NetworkDSL { /** - * Create [CertSynopsis] from [String] fingerprint. + * Create [Node] from [String] fingerprint. */ - fun CertSynopsis(fingerprint: String): CertSynopsis = - CertSynopsis(Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf()) + fun CertSynopsis(fingerprint: String): Node = + Node(Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf()) /** - * Create [CertSynopsis] from [String] fingerprint and non-revoked [userId]. + * Create [Node] from [String] fingerprint and non-revoked [userId]. */ - fun CertSynopsis(fingerprint: String, userId: String): CertSynopsis = CertSynopsis( + fun CertSynopsis(fingerprint: String, userId: String): Node = Node( Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf(userId to RevocationState.notRevoked())) - fun CertSynopsis(original: CertSynopsis, userId: String): CertSynopsis = CertSynopsis( + fun CertSynopsis(original: Node, userId: String): Node = Node( original.fingerprint, original.expirationTime, original.revocationState, original.userIds.plus(userId to RevocationState.notRevoked()) ) /** - * Create [Certification] from two [CertSynopsis] nodes. + * Create [Edge] from two [Node] nodes. */ - fun Certification(issuer: CertSynopsis, target: CertSynopsis): Certification = - Certification(issuer, target, null, Date()) + fun Certification(issuer: Node, target: Node): Edge = + Edge(issuer, target, null, Date()) /** - * Create [Certification] from two [CertSynopsis] nodes and a target [userId]. + * Create [Edge] from two [Node] nodes and a target [userId]. */ - fun Certification(issuer: CertSynopsis, target: CertSynopsis, userId: String): Certification = - Certification(issuer, target, userId, Date()) + fun Certification(issuer: Node, target: Node, userId: String): Edge = + Edge(issuer, target, userId, Date()) - fun Certification(issuer: CertSynopsis, target: CertSynopsis, amount: Int, depth: Depth): Certification = - Certification(issuer, target, null, Date(), null, true, amount, depth, RegexSet.wildcard()) + fun Certification(issuer: Node, target: Node, amount: Int, depth: Depth): Edge = + Edge(issuer, target, null, Date(), null, true, amount, depth, RegexSet.wildcard()) /** - * Add a single [CertSynopsis] built from a [String] fingerprint to the builder. + * Add a single [Node] built from a [String] fingerprint to the builder. */ fun Network.Builder.addNode(fingerprint: String): Network.Builder { return addNode(CertSynopsis(fingerprint)) } /** - * Add a single [CertSynopsis] built from a [String] fingerprint and [userId] to the builder. + * 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)) } /** - * Add multiple [CertSynopsis] nodes built from [String] fingerprints to the builder. + * Add multiple [Node] nodes built from [String] fingerprints to the builder. */ fun Network.Builder.addNodes(vararg fingerprints: String) { for (fingerprint in fingerprints) { @@ -67,8 +67,8 @@ interface NetworkDSL { } /** - * Add an edge between the [CertSynopsis] with fingerprint [issuer] and - * the [CertSynopsis] with fingerprint [target]. + * Add an edge between the [Node] with fingerprint [issuer] and + * the [Node] with fingerprint [target]. * If either the issuer or target node doesn't exist, throw an [IllegalArgumentException]. */ fun Network.Builder.addEdge(issuer: String, target: String): Network.Builder { @@ -78,8 +78,8 @@ interface NetworkDSL { } /** - * Add an edge for [userId] between the [CertSynopsis] with fingerprint [issuer] and - * the [CertSynopsis] with fingerprint [target]. + * Add an edge for [userId] between the [Node] with fingerprint [issuer] and + * the [Node] with fingerprint [target]. * If either the issuer or target node doesn't exist, throw an [IllegalArgumentException]. */ fun Network.Builder.addEdge(issuer: String, target: String, userId: String): Network.Builder { @@ -113,13 +113,13 @@ interface NetworkDSL { 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(Certification(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), RegexSet.wildcard())) + return addEdge(Edge(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(Certification(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), regexSet)) + return addEdge(Edge(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), regexSet)) } /** @@ -129,27 +129,27 @@ interface NetworkDSL { return setReferenceTime(ReferenceTime.now()) } - fun Network.getEdgesFor(issuer: Fingerprint, target: Fingerprint): CertificationSet? { - return edges[issuer]?.find { it.target.fingerprint == target } + fun Network.getEdgesFor(issuer: Fingerprint, target: Fingerprint): EdgeSet? { + return edgeSet[issuer]?.find { it.target.fingerprint == target } } - fun Network.getEdgesFor(issuer: String, target: String): CertificationSet? { + fun Network.getEdgesFor(issuer: String, target: String): EdgeSet? { return getEdgesFor(Fingerprint(issuer), Fingerprint(target)) } - fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint): List? { + fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint): List? { return getEdgeFor(issuer, target, null) } - fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint, userId: String?): List? { + fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint, userId: String?): List? { return getEdgesFor(issuer, target)?.certifications?.get(userId) } - fun Network.getEdgeFor(issuer: String, target: String): List? { + fun Network.getEdgeFor(issuer: String, target: String): List? { return getEdgeFor(issuer, target, null) } - fun Network.getEdgeFor(issuer: String, target: String, userId: String?): List? { + fun Network.getEdgeFor(issuer: String, target: String, userId: String?): List? { return getEdgeFor(Fingerprint(issuer), Fingerprint(target), userId) } diff --git a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NetworkTest.kt b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NetworkTest.kt index 0e96b434..2941d737 100644 --- a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NetworkTest.kt +++ b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NetworkTest.kt @@ -19,8 +19,8 @@ class NetworkTest: NetworkDSL { val referenceTime = now() val network = empty(referenceTime) assert(network.nodes.isEmpty()) - assert(network.edges.isEmpty()) - assert(network.reverseEdges.isEmpty()) + assert(network.edgeSet.isEmpty()) + assert(network.reverseEdgeSet.isEmpty()) assertEquals(referenceTime, network.referenceTime) assertEquals(0, network.numberOfEdges) assertEquals(0, network.numberOfSignatures) @@ -57,7 +57,7 @@ class NetworkTest: NetworkDSL { buildEdge("A", "C", "Charlie ") } - assertEquals("Network with 3 nodes, 2 edges:\n" + + assertEquals("Network with 3 nodes, 2 edgeSet:\n" + "A certifies binding: null <-> B [120]\n" + "A certifies binding: Charlie <-> C [120]\n", network.toString()) diff --git a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertSynopsisTest.kt b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NodeTest.kt similarity index 94% rename from wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertSynopsisTest.kt rename to wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NodeTest.kt index ebbc6b2b..5ca348a0 100644 --- a/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/CertSynopsisTest.kt +++ b/wot-dijkstra/src/test/kotlin/org/pgpainless/wot/dijkstra/NodeTest.kt @@ -7,7 +7,7 @@ package org.pgpainless.wot.dijkstra import org.junit.jupiter.api.Test import kotlin.test.assertEquals -class CertSynopsisTest: NetworkDSL { +class NodeTest: NetworkDSL { @Test fun `Fingerprint 'A' toString`() {