mirror of
https://github.com/corda/corda.git
synced 2024-12-27 08:22:35 +00:00
Introducing the InputReader interface (#102)
* Introducing the InputReader interface * Addressing review comments * Addressing review comments
This commit is contained in:
parent
c56ea4088f
commit
fffcdb47da
@ -125,7 +125,7 @@ dependencies {
|
||||
testCompile "com.nhaarman:mockito-kotlin:0.6.1"
|
||||
testRuntime "net.corda:corda-rpc:$corda_dependency_version"
|
||||
testCompile "com.spotify:docker-client:8.9.1"
|
||||
integrationTestCompile "net.corda:corda-test-utils:$corda_dependency_version"
|
||||
integrationTestCompile "net.corda:corda-test-common:$corda_dependency_version"
|
||||
integrationTestRuntime "net.corda:corda-rpc:$corda_dependency_version"
|
||||
|
||||
compile('com.atlassian.jira:jira-rest-java-client-core:4.0.0') {
|
||||
|
@ -5,12 +5,12 @@ import com.nhaarman.mockito_kotlin.mock
|
||||
import com.nhaarman.mockito_kotlin.whenever
|
||||
import com.r3.corda.networkmanage.HsmSimulator
|
||||
import com.r3.corda.networkmanage.hsm.authentication.Authenticator
|
||||
import com.r3.corda.networkmanage.hsm.authentication.InputReader
|
||||
import com.r3.corda.networkmanage.hsm.authentication.createProvider
|
||||
import com.r3.corda.networkmanage.hsm.configuration.Parameters
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.io.Console
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class HsmTest {
|
||||
@ -19,11 +19,11 @@ class HsmTest {
|
||||
@JvmField
|
||||
val hsmSimulator: HsmSimulator = HsmSimulator()
|
||||
|
||||
private var console: Console? = null
|
||||
private lateinit var inputReader: InputReader
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
console = mock()
|
||||
inputReader = mock()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -35,9 +35,9 @@ class HsmTest {
|
||||
keySpecifier = 1,
|
||||
keyGroup = "*"
|
||||
)
|
||||
whenever(console?.readLine()).thenReturn(hsmSimulator.cryptoUserCredentials().username)
|
||||
whenever(console?.readPassword(any())).thenReturn(hsmSimulator.cryptoUserCredentials().password.toCharArray())
|
||||
val authenticator = Authenticator(parameters.createProvider(), console = console)
|
||||
whenever(inputReader.readLine()).thenReturn(hsmSimulator.cryptoUserCredentials().username)
|
||||
whenever(inputReader.readPassword(any())).thenReturn(hsmSimulator.cryptoUserCredentials().password)
|
||||
val authenticator = Authenticator(parameters.createProvider(), inputReader = inputReader)
|
||||
var executed = false
|
||||
|
||||
// when
|
||||
|
@ -4,7 +4,6 @@ import CryptoServerJCE.CryptoServerProvider
|
||||
import com.r3.corda.networkmanage.hsm.configuration.Parameters
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.Console
|
||||
import java.nio.file.Path
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
@ -17,7 +16,7 @@ class Authenticator(private val provider: CryptoServerProvider,
|
||||
private val authKeyFilePath: Path? = null,
|
||||
private val authKeyFilePass: String? = null,
|
||||
private val authStrengthThreshold: Int = 2,
|
||||
val console: Console? = System.console()) {
|
||||
inputReader: InputReader = ConsoleInputReader()) : InputReader by inputReader {
|
||||
|
||||
/**
|
||||
* Interactively (using console) authenticates a user against the HSM. Once authentication is successful the
|
||||
@ -32,7 +31,7 @@ class Authenticator(private val provider: CryptoServerProvider,
|
||||
loop@ while (true) {
|
||||
val user = if (autoUsername.isNullOrEmpty()) {
|
||||
print("Enter User Name (or Q to quit): ")
|
||||
val input = readConsoleLine(console)
|
||||
val input = readLine()
|
||||
if (input != null && "q" == input.toLowerCase()) {
|
||||
authenticated.clear()
|
||||
break
|
||||
@ -47,7 +46,7 @@ class Authenticator(private val provider: CryptoServerProvider,
|
||||
AuthMode.KEY_FILE -> {
|
||||
println("Authenticating using preconfigured key file")
|
||||
val password = if (authKeyFilePass == null) {
|
||||
val input = readPassword("Enter key file password (or Q to quit): ", console)
|
||||
val input = readPassword("Enter key file password (or Q to quit): ")
|
||||
if ("q" == input.toLowerCase()) {
|
||||
authenticated.clear()
|
||||
break@loop
|
||||
@ -60,7 +59,7 @@ class Authenticator(private val provider: CryptoServerProvider,
|
||||
provider.loginSign(user, authKeyFilePath.toString(), password)
|
||||
}
|
||||
AuthMode.PASSWORD -> {
|
||||
val password = readPassword("Enter password (or Q to quit): ", console)
|
||||
val password = readPassword("Enter password (or Q to quit): ")
|
||||
if ("q" == password.toLowerCase()) {
|
||||
authenticated.clear()
|
||||
break@loop
|
||||
@ -125,23 +124,4 @@ fun Parameters.createProvider(): CryptoServerProvider {
|
||||
val provider = CryptoServerProvider(cfg)
|
||||
cfg.close()
|
||||
return provider
|
||||
}
|
||||
|
||||
/** Read password from console, do a readLine instead if console is null (e.g. when debugging in IDE). */
|
||||
internal fun readPassword(fmt: String, console: Console? = System.console()): String {
|
||||
return if (console != null) {
|
||||
String(console.readPassword(fmt))
|
||||
} else {
|
||||
print(fmt)
|
||||
readLine()!!
|
||||
}
|
||||
}
|
||||
|
||||
/** Read console line */
|
||||
internal fun readConsoleLine(console: Console?): String? {
|
||||
return if (console == null) {
|
||||
readLine()
|
||||
} else {
|
||||
console.readLine()
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.r3.corda.networkmanage.hsm.authentication
|
||||
|
||||
/**
|
||||
* User input reader interface
|
||||
*/
|
||||
interface InputReader {
|
||||
/**
|
||||
* Reads a single line from user's input.
|
||||
*/
|
||||
fun readLine(): String?
|
||||
|
||||
/**
|
||||
* Reads a single line from user's input. The characters from the input are masked while being entered.
|
||||
* @param format message string displayed before user's input
|
||||
*/
|
||||
fun readPassword(format: String): String
|
||||
}
|
||||
|
||||
class ConsoleInputReader : InputReader {
|
||||
private val console = System.console()
|
||||
|
||||
/** Read password from console, do a readLine instead if console is null (e.g. when debugging in IDE). */
|
||||
override fun readPassword(format: String): String {
|
||||
return if (console != null) {
|
||||
String(console.readPassword(format))
|
||||
} else {
|
||||
print(format)
|
||||
kotlin.io.readLine() ?: throw IllegalArgumentException("Password required")
|
||||
}
|
||||
}
|
||||
|
||||
/** Read console line */
|
||||
override fun readLine(): String? {
|
||||
return if (console == null) {
|
||||
kotlin.io.readLine()
|
||||
} else {
|
||||
console.readLine()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package com.r3.corda.networkmanage.hsm.signer
|
||||
|
||||
import com.r3.corda.networkmanage.hsm.authentication.Authenticator
|
||||
import com.r3.corda.networkmanage.hsm.authentication.readPassword
|
||||
import com.r3.corda.networkmanage.hsm.persistence.ApprovedCertificateRequestData
|
||||
import com.r3.corda.networkmanage.hsm.persistence.SignedCertificateRequestStorage
|
||||
import com.r3.corda.networkmanage.hsm.utils.X509Utilities.buildCertPath
|
||||
@ -36,7 +35,7 @@ class HsmCsrSigner(private val storage: SignedCertificateRequestStorage,
|
||||
// This should be changed once we allow for more certificates in the chain. Preferably we should use
|
||||
// keyStore.getCertificateChain(String) and assume entire chain is stored in the HSM (depending on the support).
|
||||
val caParentCertificate = keyStore.getCertificate(caParentCertificateName)
|
||||
val caPrivateKeyPass = caPrivateKeyPass ?: readPassword("CA Private Key Password: ", authenticator.console)
|
||||
val caPrivateKeyPass = caPrivateKeyPass ?: authenticator.readPassword("CA Private Key Password: ")
|
||||
val caCertAndKey = retrieveCertificateAndKeys(caCertificateName, caPrivateKeyPass, keyStore)
|
||||
toSign.forEach {
|
||||
it.certPath = buildCertPath(createClientCertificate(caCertAndKey, it.request, validDays, provider), caParentCertificate)
|
||||
|
@ -5,20 +5,19 @@ import com.nhaarman.mockito_kotlin.*
|
||||
import com.r3.corda.networkmanage.TestBase
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.io.Console
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class AuthenticatorTest : TestBase() {
|
||||
|
||||
private lateinit var provider: CryptoServerProvider
|
||||
private lateinit var console: Console
|
||||
private lateinit var inputReader: InputReader
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
provider = mock()
|
||||
whenever(provider.cryptoServer).thenReturn(mock())
|
||||
console = mock()
|
||||
inputReader = mock()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -28,7 +27,7 @@ class AuthenticatorTest : TestBase() {
|
||||
var executed = false
|
||||
|
||||
// when
|
||||
Authenticator(provider = provider, console = console).connectAndAuthenticate { _, _ -> executed = true }
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _ -> executed = true }
|
||||
|
||||
// then
|
||||
assertFalse(executed)
|
||||
@ -47,7 +46,7 @@ class AuthenticatorTest : TestBase() {
|
||||
var executed = false
|
||||
|
||||
// when
|
||||
Authenticator(provider = provider, console = console).connectAndAuthenticate { _, _ -> executed = true }
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _ -> executed = true }
|
||||
|
||||
// then
|
||||
verify(provider).loginPassword(username, password)
|
||||
@ -64,7 +63,7 @@ class AuthenticatorTest : TestBase() {
|
||||
var executed = false
|
||||
|
||||
// when
|
||||
Authenticator(provider = provider, console = console, mode = AuthMode.CARD_READER).connectAndAuthenticate { _, _ -> executed = true }
|
||||
Authenticator(provider = provider, inputReader = inputReader, mode = AuthMode.CARD_READER).connectAndAuthenticate { _, _ -> executed = true }
|
||||
|
||||
// then
|
||||
verify(provider).loginSign(username, ":cs2:cyb:USB0", null)
|
||||
@ -83,7 +82,7 @@ class AuthenticatorTest : TestBase() {
|
||||
var executed = false
|
||||
|
||||
// when
|
||||
Authenticator(provider = provider, console = console).connectAndAuthenticate { _, _ -> executed = true }
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _ -> executed = true }
|
||||
|
||||
// then
|
||||
verify(provider, times(3)).loginPassword(username, password)
|
||||
@ -99,11 +98,11 @@ class AuthenticatorTest : TestBase() {
|
||||
}
|
||||
|
||||
private fun givenUserConsoleInputOnReadPassword(input: String) {
|
||||
whenever(console.readPassword(any<String>())).thenReturn(input.toCharArray())
|
||||
whenever(inputReader.readPassword(any<String>())).thenReturn(input)
|
||||
}
|
||||
|
||||
private fun givenUserConsoleInputOnReadLine(input: String) {
|
||||
whenever(console.readLine()).thenReturn(input)
|
||||
whenever(inputReader.readLine()).thenReturn(input)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user