mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-26 04:47:59 +01:00
Work on API structure and first baby steps of formatting the Authenticate output
This commit is contained in:
parent
5d15a18e6b
commit
96cfd71e60
15 changed files with 330 additions and 35 deletions
|
@ -6,9 +6,10 @@ package org.pgpainless.wot.cli
|
||||||
|
|
||||||
import org.pgpainless.certificate_store.PGPainlessCertD
|
import org.pgpainless.certificate_store.PGPainlessCertD
|
||||||
import org.pgpainless.util.DateUtil
|
import org.pgpainless.util.DateUtil
|
||||||
|
import org.pgpainless.wot.api.WoTAPI
|
||||||
import org.pgpainless.wot.cli.subcommands.*
|
import org.pgpainless.wot.cli.subcommands.*
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||||
import org.pgpainless.wot.dijkstra.sq.ReferenceTime
|
import org.pgpainless.wot.dijkstra.sq.ReferenceTime
|
||||||
import pgp.cert_d.PGPCertificateDirectory
|
|
||||||
import pgp.cert_d.PGPCertificateStoreAdapter
|
import pgp.cert_d.PGPCertificateStoreAdapter
|
||||||
import pgp.cert_d.subkey_lookup.InMemorySubkeyLookupFactory
|
import pgp.cert_d.subkey_lookup.InMemorySubkeyLookupFactory
|
||||||
import pgp.certificate_store.PGPCertificateStore
|
import pgp.certificate_store.PGPCertificateStore
|
||||||
|
@ -65,25 +66,32 @@ class WotCLI: Callable<Int> {
|
||||||
@Option(names = ["--time"], description = ["Reference time."])
|
@Option(names = ["--time"], description = ["Reference time."])
|
||||||
var time: String? = null
|
var time: String? = null
|
||||||
|
|
||||||
fun getReferenceTime(): ReferenceTime {
|
private val referenceTime: ReferenceTime
|
||||||
return if (time == null) {
|
get() {
|
||||||
ReferenceTime.now()
|
return if (time == null) {
|
||||||
} else {
|
ReferenceTime.now()
|
||||||
val date = DateUtil.parseUTCDate(time)
|
} else {
|
||||||
ReferenceTime.timestamp(date)
|
val date = DateUtil.parseUTCDate(time)
|
||||||
|
ReferenceTime.timestamp(date)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun getCertificateStore(): PGPCertificateStore {
|
private val certificateStore: PGPCertificateStore
|
||||||
requireNotNull(certificateSource.pgpCertD) {
|
get() {
|
||||||
"Currently, only --cert-d is supported."
|
requireNotNull(certificateSource.pgpCertD) {
|
||||||
|
"Currently, only --cert-d is supported."
|
||||||
|
}
|
||||||
|
val certD = PGPainlessCertD.fileBased(
|
||||||
|
certificateSource.pgpCertD,
|
||||||
|
InMemorySubkeyLookupFactory())
|
||||||
|
|
||||||
|
return PGPCertificateStoreAdapter(certD)
|
||||||
}
|
}
|
||||||
val certD = PGPainlessCertD.fileBased(
|
|
||||||
certificateSource.pgpCertD,
|
|
||||||
InMemorySubkeyLookupFactory())
|
|
||||||
|
|
||||||
return PGPCertificateStoreAdapter(certD)
|
private val trustRoots: List<Fingerprint>
|
||||||
}
|
get() {
|
||||||
|
return trustRoot.map { Fingerprint(it) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the command.
|
* Execute the command.
|
||||||
|
@ -99,6 +107,17 @@ class WotCLI: Callable<Int> {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val api: WoTAPI
|
||||||
|
get() {
|
||||||
|
return WoTAPI(
|
||||||
|
certStores = listOf(certificateStore),
|
||||||
|
trustRoots = trustRoots,
|
||||||
|
gossip = false,
|
||||||
|
certificationNetwork = false,
|
||||||
|
trustAmount = amount,
|
||||||
|
referenceTime = referenceTime)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun main(args: Array<String>): Unit = exitProcess(CommandLine(WotCLI()).execute(*args))
|
fun main(args: Array<String>): Unit = exitProcess(CommandLine(WotCLI()).execute(*args))
|
||||||
|
|
|
@ -6,10 +6,13 @@ package org.pgpainless.wot.cli.subcommands
|
||||||
|
|
||||||
import org.pgpainless.wot.api.AuthenticateAPI
|
import org.pgpainless.wot.api.AuthenticateAPI
|
||||||
import org.pgpainless.wot.cli.WotCLI
|
import org.pgpainless.wot.cli.WotCLI
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Path
|
||||||
import picocli.CommandLine
|
import picocli.CommandLine
|
||||||
import picocli.CommandLine.Command
|
import picocli.CommandLine.Command
|
||||||
import picocli.CommandLine.Parameters
|
import picocli.CommandLine.Parameters
|
||||||
import picocli.CommandLine.ParentCommand
|
import picocli.CommandLine.ParentCommand
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
|
|
||||||
@Command(name = "authenticate")
|
@Command(name = "authenticate")
|
||||||
|
@ -27,12 +30,46 @@ class AuthenticateCmd: Callable<Int> {
|
||||||
@CommandLine.Option(names = ["--email"], description = ["Consider all user-IDs that contain the given email address."])
|
@CommandLine.Option(names = ["--email"], description = ["Consider all user-IDs that contain the given email address."])
|
||||||
var email = false
|
var email = false
|
||||||
|
|
||||||
|
private val dateFormat: SimpleDateFormat = SimpleDateFormat("yyyy-MM-dd")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the command.
|
* Execute the command.
|
||||||
* @return exit code
|
* @return exit code
|
||||||
*/
|
*/
|
||||||
override fun call(): Int {
|
override fun call(): Int {
|
||||||
val api = AuthenticateAPI()
|
val result = parent.api.authenticate(AuthenticateAPI.Arguments(
|
||||||
TODO("Not yet implemented")
|
Fingerprint(fingerprint), userId, email))
|
||||||
|
print(formatResult(result))
|
||||||
|
if (result.percentage < 100) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun formatResult(result: AuthenticateAPI.Result): String {
|
||||||
|
if (result.percentage < 100) {
|
||||||
|
return "No paths found."
|
||||||
|
}
|
||||||
|
|
||||||
|
val sb = StringBuilder()
|
||||||
|
sb.appendLine("[✓] ${result.fingerprint} ${result.userId}: fully authenticated (${result.percentage}%)")
|
||||||
|
for ((pIndex, path: Path) in result.paths.paths.withIndex()) {
|
||||||
|
sb.appendLine(" Path #${pIndex + 1} of ${result.paths.paths.size}, trust amount ${path.amount}:")
|
||||||
|
for ((cIndex, certification) in path.certifications.withIndex()) {
|
||||||
|
val issuerUserId = certification.issuer.userIds.keys.firstOrNull()?.let { " (\"${it}\")" } ?: ""
|
||||||
|
when (cIndex) {
|
||||||
|
0 -> {
|
||||||
|
sb.appendLine(" ◯ ${certification.issuer.fingerprint}${issuerUserId}")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
sb.appendLine(" ├ ${certification.issuer.fingerprint}${issuerUserId}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.appendLine(" │ certified the following binding on ${dateFormat.format(certification.creationTime)}")
|
||||||
|
}
|
||||||
|
sb.appendLine(" └ ${result.fingerprint} \"${result.userId}\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.cli.subcommands
|
package org.pgpainless.wot.cli.subcommands
|
||||||
|
|
||||||
import org.pgpainless.wot.api.IdentifyAPI
|
|
||||||
import org.pgpainless.wot.cli.WotCLI
|
import org.pgpainless.wot.cli.WotCLI
|
||||||
import picocli.CommandLine
|
import picocli.CommandLine
|
||||||
import picocli.CommandLine.Command
|
import picocli.CommandLine.Command
|
||||||
|
@ -26,7 +25,7 @@ class IdentifyCmd: Callable<Int> {
|
||||||
* @return exit code
|
* @return exit code
|
||||||
*/
|
*/
|
||||||
override fun call(): Int {
|
override fun call(): Int {
|
||||||
val api = IdentifyAPI()
|
val api = parent.api
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.cli.subcommands
|
package org.pgpainless.wot.cli.subcommands
|
||||||
|
|
||||||
import org.pgpainless.wot.api.ListAPI
|
|
||||||
import org.pgpainless.wot.cli.WotCLI
|
import org.pgpainless.wot.cli.WotCLI
|
||||||
import picocli.CommandLine
|
import picocli.CommandLine
|
||||||
import picocli.CommandLine.Command
|
import picocli.CommandLine.Command
|
||||||
|
@ -22,7 +21,7 @@ class ListCmd: Callable<Int> {
|
||||||
* @return exit code
|
* @return exit code
|
||||||
*/
|
*/
|
||||||
override fun call(): Int {
|
override fun call(): Int {
|
||||||
val api = ListAPI()
|
val api = parent.api
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.cli.subcommands
|
package org.pgpainless.wot.cli.subcommands
|
||||||
|
|
||||||
import org.pgpainless.wot.api.LookupAPI
|
|
||||||
import org.pgpainless.wot.cli.WotCLI
|
import org.pgpainless.wot.cli.WotCLI
|
||||||
import picocli.CommandLine.*
|
import picocli.CommandLine.*
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
|
@ -27,7 +26,7 @@ class LookupCmd: Callable<Int> {
|
||||||
* @return exit code
|
* @return exit code
|
||||||
*/
|
*/
|
||||||
override fun call(): Int {
|
override fun call(): Int {
|
||||||
val api = LookupAPI()
|
val api = parent.api
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.cli.subcommands
|
package org.pgpainless.wot.cli.subcommands
|
||||||
|
|
||||||
import org.pgpainless.wot.api.PathAPI
|
|
||||||
import org.pgpainless.wot.cli.WotCLI
|
import org.pgpainless.wot.cli.WotCLI
|
||||||
import picocli.CommandLine
|
import picocli.CommandLine
|
||||||
import picocli.CommandLine.Command
|
import picocli.CommandLine.Command
|
||||||
|
@ -29,7 +28,7 @@ class PathCmd: Callable<Int> {
|
||||||
* @return exit code
|
* @return exit code
|
||||||
*/
|
*/
|
||||||
override fun call(): Int {
|
override fun call(): Int {
|
||||||
val api = PathAPI()
|
val api = parent.api
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.pgpainless.wot.cli.subcommands
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.pgpainless.wot.api.AuthenticateAPI
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.*
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class AuthenticateCmdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFormatting() {
|
||||||
|
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
|
||||||
|
val cmd = AuthenticateCmd()
|
||||||
|
val paths = Paths()
|
||||||
|
val neal = CertSynopsis(
|
||||||
|
Fingerprint("F7173B3C7C685CD9ECC4191B74E445BA0E15C957"),
|
||||||
|
null,
|
||||||
|
RevocationState.notRevoked(),
|
||||||
|
mapOf(
|
||||||
|
Pair("Neal H. Walfield (Code Signing Key) <neal@pep.foundation>", RevocationState.notRevoked())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val justus = CertSynopsis(
|
||||||
|
Fingerprint("CBCD8F030588653EEDD7E2659B7DD433F254904A"),
|
||||||
|
null,
|
||||||
|
RevocationState.notRevoked(),
|
||||||
|
mapOf(
|
||||||
|
Pair("Justus Winter <justus@sequoia-pgp.org>", RevocationState.notRevoked())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val certification = Certification(
|
||||||
|
neal,
|
||||||
|
justus,
|
||||||
|
"Justus Winter <justus@sequoia-pgp.org>",
|
||||||
|
dateFormat.parse("2022-02-04"),
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
120,
|
||||||
|
Depth.limited(0),
|
||||||
|
RegexSet.wildcard())
|
||||||
|
paths.add(Path(neal, mutableListOf(certification), Depth.auto(0)), 120)
|
||||||
|
val testResult = AuthenticateAPI.Result(
|
||||||
|
Fingerprint("CBCD8F030588653EEDD7E2659B7DD433F254904A"),
|
||||||
|
"Justus Winter <justus@sequoia-pgp.org>",
|
||||||
|
120,
|
||||||
|
paths)
|
||||||
|
|
||||||
|
val formatted = cmd.formatResult(testResult)
|
||||||
|
assertEquals(buildString {
|
||||||
|
append("[✓] CBCD8F030588653EEDD7E2659B7DD433F254904A Justus Winter <justus@sequoia-pgp.org>: fully authenticated (100%)\n")
|
||||||
|
append(" Path #1 of 1, trust amount 120:\n")
|
||||||
|
append(" ◯ F7173B3C7C685CD9ECC4191B74E445BA0E15C957 (\"Neal H. Walfield (Code Signing Key) <neal@pep.foundation>\")\n")
|
||||||
|
append(" │ certified the following binding on 2022-02-04\n")
|
||||||
|
append(" └ CBCD8F030588653EEDD7E2659B7DD433F254904A \"Justus Winter <justus@sequoia-pgp.org>\"\n")
|
||||||
|
}, formatted)
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,10 +4,46 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.api
|
package org.pgpainless.wot.api
|
||||||
|
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Paths
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.ReferenceTime
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticate a binding.
|
* Authenticate a binding.
|
||||||
* A binding is a pair consisting of a certificate and a User ID.
|
* A binding is a pair consisting of a certificate and a User ID.
|
||||||
*/
|
*/
|
||||||
class AuthenticateAPI {
|
interface AuthenticateAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate the binding between a fingerprint and a given userId.
|
||||||
|
*
|
||||||
|
* @param arguments arguments
|
||||||
|
*/
|
||||||
|
fun authenticate(arguments: Arguments): Result
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundle for arguments to the authenticate operation.
|
||||||
|
* @param fingerprint fingerprint of the certificate
|
||||||
|
* @param userId user-ID for which we want to authenticate a binding to the certificate
|
||||||
|
* @param email if true, consider [userId] to be an email address and consider all bindings containing it
|
||||||
|
*/
|
||||||
|
data class Arguments(
|
||||||
|
var fingerprint: Fingerprint,
|
||||||
|
var userId: String,
|
||||||
|
var email: Boolean = false)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication result.
|
||||||
|
* @param targetAmount the targeted trust amount required to achieve full authentication
|
||||||
|
* @param paths the number of paths
|
||||||
|
*/
|
||||||
|
data class Result(val fingerprint: Fingerprint, val userId: String, private val targetAmount: Int, val paths: Paths) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Percentage of authentication. 100% means fully authenticated binding.
|
||||||
|
*/
|
||||||
|
val percentage: Int
|
||||||
|
get() = paths.amount * 100 / targetAmount
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package org.pgpainless.wot.api
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum for different levels of Trust.
|
||||||
|
*/
|
||||||
|
enum class AuthenticationLevel(val amount: Int) {
|
||||||
|
/**
|
||||||
|
* With an amount of 40, a binding is considered partially trusted.
|
||||||
|
*/
|
||||||
|
Partially(40),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An amount if 120 is sufficient to fully authenticate a binding.
|
||||||
|
*/
|
||||||
|
Fully(120),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A trust amount of 240 means the binding is doubly authenticated.
|
||||||
|
*/
|
||||||
|
Doubly(240)
|
||||||
|
}
|
|
@ -4,6 +4,14 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.api
|
package org.pgpainless.wot.api
|
||||||
|
|
||||||
class IdentifyAPI {
|
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Paths
|
||||||
|
|
||||||
|
interface IdentifyAPI {
|
||||||
|
|
||||||
|
fun identify(arguments: Arguments): Result
|
||||||
|
|
||||||
|
data class Arguments(val fingerprint: Fingerprint)
|
||||||
|
|
||||||
|
data class Result(val paths: Paths)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.api
|
package org.pgpainless.wot.api
|
||||||
|
|
||||||
class ListAPI {
|
import org.pgpainless.wot.dijkstra.sq.Paths
|
||||||
|
|
||||||
|
interface ListAPI {
|
||||||
|
|
||||||
|
fun list(): Result
|
||||||
|
|
||||||
|
data class Result(val paths: Paths)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,13 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.api
|
package org.pgpainless.wot.api
|
||||||
|
|
||||||
class LookupAPI {
|
import org.pgpainless.wot.dijkstra.sq.Paths
|
||||||
|
|
||||||
|
interface LookupAPI {
|
||||||
|
|
||||||
|
fun lookup(arguments: Arguments): Result
|
||||||
|
|
||||||
|
data class Arguments(val userId: String, val email: Boolean = false)
|
||||||
|
|
||||||
|
data class Result(val paths: Paths)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,28 @@
|
||||||
|
|
||||||
package org.pgpainless.wot.api
|
package org.pgpainless.wot.api
|
||||||
|
|
||||||
class PathAPI {
|
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||||
|
|
||||||
|
interface PathAPI {
|
||||||
|
|
||||||
|
fun path(arguments: Arguments): Result
|
||||||
|
|
||||||
|
data class Arguments(val rootFingerprint: Fingerprint, val pathFingerprints: List<Fingerprint>, val userId: String)
|
||||||
|
|
||||||
|
interface Result {
|
||||||
|
|
||||||
|
fun isSuccess(): Boolean
|
||||||
|
|
||||||
|
class Success: Result {
|
||||||
|
override fun isSuccess(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Failure(val information: List<String>): Result {
|
||||||
|
override fun isSuccess(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package org.pgpainless.wot.api
|
||||||
|
|
||||||
|
import org.pgpainless.certificate_store.PGPainlessCertD
|
||||||
|
import org.pgpainless.util.NotationRegistry
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.ReferenceTime
|
||||||
|
import pgp.cert_d.PGPCertificateStoreAdapter
|
||||||
|
import pgp.cert_d.subkey_lookup.InMemorySubkeyLookupFactory
|
||||||
|
import pgp.certificate_store.PGPCertificateStore
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web of Trust API, offering different operations.
|
||||||
|
*
|
||||||
|
* @param certStores one or more [PGPCertificateStores][PGPCertificateStore] to retrieve certificates from.
|
||||||
|
* @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
|
||||||
|
* @param trustAmount minimum trust amount
|
||||||
|
* @param referenceTime reference time at which the web of trust is evaluated
|
||||||
|
* @param knownNotationRegistry registry of known notations
|
||||||
|
*/
|
||||||
|
class WoTAPI(
|
||||||
|
val certStores: List<PGPCertificateStore> = getDefaultCertStores(),
|
||||||
|
val trustRoots: List<Fingerprint>,
|
||||||
|
val gossip: Boolean = false,
|
||||||
|
val certificationNetwork: Boolean = false,
|
||||||
|
val trustAmount: Int = AuthenticationLevel.Fully.amount,
|
||||||
|
val referenceTime: ReferenceTime = ReferenceTime.now(),
|
||||||
|
val knownNotationRegistry: NotationRegistry = NotationRegistry()
|
||||||
|
): AuthenticateAPI, IdentifyAPI, ListAPI, LookupAPI, PathAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Secondary constructor, taking an [AuthenticationLevel] instead of an [Int].
|
||||||
|
*/
|
||||||
|
constructor(certStores: List<PGPCertificateStore> = getDefaultCertStores(),
|
||||||
|
trustRoots: List<Fingerprint>,
|
||||||
|
gossip: Boolean = false,
|
||||||
|
certificationNetwork: Boolean = false,
|
||||||
|
trustAmount: AuthenticationLevel = AuthenticationLevel.Fully,
|
||||||
|
referenceTime: ReferenceTime = ReferenceTime.now(),
|
||||||
|
knownNotationRegistry: NotationRegistry = NotationRegistry()):
|
||||||
|
this(certStores,trustRoots, gossip,certificationNetwork, trustAmount.amount, referenceTime, knownNotationRegistry)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun getDefaultCertStores(): List<PGPCertificateStore> {
|
||||||
|
val certD = PGPainlessCertD.fileBased(InMemorySubkeyLookupFactory())
|
||||||
|
val asStore = PGPCertificateStoreAdapter(certD)
|
||||||
|
return listOf(asStore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun authenticate(arguments: AuthenticateAPI.Arguments): AuthenticateAPI.Result {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun identify(arguments: IdentifyAPI.Arguments): IdentifyAPI.Result {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun list(): ListAPI.Result {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun lookup(arguments: LookupAPI.Arguments): LookupAPI.Result {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun path(arguments: PathAPI.Arguments): PathAPI.Result {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,15 +7,20 @@ package org.pgpainless.wot.dijkstra.sq
|
||||||
/**
|
/**
|
||||||
* List of individual [Paths][Path].
|
* List of individual [Paths][Path].
|
||||||
*
|
*
|
||||||
* @param paths list of paths
|
* @param _paths list of paths
|
||||||
*/
|
*/
|
||||||
class Paths(private val paths: MutableList<Item>) {
|
class Paths(private val _paths: MutableList<Item>) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty collection of paths.
|
* Empty collection of paths.
|
||||||
*/
|
*/
|
||||||
constructor(): this(mutableListOf<Item>())
|
constructor(): this(mutableListOf<Item>())
|
||||||
|
|
||||||
|
val paths: List<Path>
|
||||||
|
get() {
|
||||||
|
return _paths.map { it.path }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a [Path] to the list.
|
* Add a [Path] to the list.
|
||||||
*
|
*
|
||||||
|
@ -25,7 +30,7 @@ class Paths(private val paths: MutableList<Item>) {
|
||||||
require(amount <= path.amount) {
|
require(amount <= path.amount) {
|
||||||
"Amount too small. TODO: Better error message"
|
"Amount too small. TODO: Better error message"
|
||||||
}
|
}
|
||||||
paths.add(Item(path, amount))
|
_paths.add(Item(path, amount))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +38,7 @@ class Paths(private val paths: MutableList<Item>) {
|
||||||
*/
|
*/
|
||||||
val amount: Int
|
val amount: Int
|
||||||
get() {
|
get() {
|
||||||
return paths.sumOf { it.amount }
|
return _paths.sumOf { it.amount }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue