All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.http4k.config.Secret.kt Maven / Gradle / Ivy

package org.http4k.config

import java.io.Closeable
import java.nio.charset.StandardCharsets.UTF_8
import java.util.concurrent.atomic.AtomicReference

/**
 * A secret is a value which tries very hard not to expose itself as a string, by storing it's value in a byte array.
 * You can "use" the value only once, after which the value is destroyed
 */
class Secret(input: ByteArray) : Closeable {
    constructor(value: String) : this(value.toByteArray(UTF_8))

    init {
        require(input.isNotEmpty()) { "Cannot create an empty secret" }
    }

    private val value = AtomicReference(input)

    private val initialHashcode = input.contentHashCode()

    override fun equals(other: Any?): Boolean = (value.get()
        ?: ByteArray(0)).contentEquals((other as Secret).value.get())

    override fun hashCode(): Int = initialHashcode

    override fun toString(): String = "Secret(hashcode = $initialHashcode)"

    fun  use(fn: (String) -> T) = with(value.get()) {
        if (isNotEmpty()) fn(toString(UTF_8))
        else throw IllegalStateException("Cannot read a secret more than once")
    }.apply { close() }

    override fun close(): Unit = run {
        value.get().apply { indices.forEach { this[it] = 0 } }
        value.set(ByteArray(0))
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy