Skip to content

Commit

Permalink
Merge pull request #819 from walt-id/wal-619-delete-aws-key
Browse files Browse the repository at this point in the history
wal-619 Delete AWS key
  • Loading branch information
philpotisk authored Nov 22, 2024
2 parents 6779027 + 6beeea6 commit 013d3ac
Show file tree
Hide file tree
Showing 14 changed files with 195 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<p class="text-base font-semibold">Generate key</p>
<div>
<div
class="mt-1 space-y-8 border-gray-900/10 pb-12 sm:space-y-0 sm:divide-y sm:divide-gray-900/10 sm:border-t sm:pb-0">
class="mt-1 space-y-8 border-gray-900/10 pb-12 sm:space-y-0 sm:divide-y sm:divide-gray-900/10 sm:border-t sm:pb-0">
<div>
<!-- Key Generation Request -->
<div class="sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-4">
Expand All @@ -13,10 +13,10 @@
</label>
<div class="mt-2 sm:col-span-2 sm:mt-0">
<select id="keyGenerationRequest" v-model="data.keyGenerationRequest.type"
@change="data.keyGenerationRequest.config = {}"
class="block px-2 w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-xs sm:text-sm sm:leading-6">
@change="data.keyGenerationRequest.config = {}"
class="block px-2 w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-xs sm:text-sm sm:leading-6">
<option v-for="option in options" :key="option.keyGenerationRequest[1]"
:value="option.keyGenerationRequest[1]">
:value="option.keyGenerationRequest[1]">
{{ option.keyGenerationRequest[0] }}
</option>
</select>
Expand All @@ -30,7 +30,7 @@
</label>
<div class="mt-2 sm:col-span-2 sm:mt-0">
<select id="keyType" v-model="data.type"
class="block px-2 w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-xs sm:text-sm sm:leading-6">
class="block px-2 w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-xs sm:text-sm sm:leading-6">
<option v-for="keyType in options.find(
(option) =>
option.keyGenerationRequest[1] ==
Expand All @@ -50,7 +50,7 @@
option.keyGenerationRequest[1] ==
data.keyGenerationRequest.type
)?.config?.length"
class="mt-1 space-y-8 border-gray-900/10 pb-12 sm:space-y-0 sm:divide-gray-900/10 sm:border-t sm:pb-0">
class="mt-1 space-y-8 border-gray-900/10 pb-12 sm:space-y-0 sm:divide-gray-900/10 sm:border-t sm:pb-0">
<div class="sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-2" v-for="config in options.find(
(option) =>
option.keyGenerationRequest[1] ==
Expand All @@ -60,11 +60,11 @@
{{ config.charAt(0).toUpperCase() + config.slice(1) }}
</label>
<textarea v-if="config.includes('signingKeyPem')" v-model="data.keyGenerationRequest.config[config]"
class="px-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6"
rows="4"></textarea>
class="px-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6"
rows="4"></textarea>
<input v-else v-model="data.keyGenerationRequest.config[config]"
class="px-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6"
type="text" />
class="px-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6"
type="text"/>
</div>
</div>
</div>
Expand All @@ -73,8 +73,8 @@
<!-- Submit Button -->
<div class="mt-2 flex items-center justify-end gap-x-6">
<button
class="inline-flex justify-center bg-blue-500 hover:bg-blue-600 focus-visible:outline-blue-600 rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
@click="generateKey">
class="inline-flex justify-center bg-blue-500 hover:bg-blue-600 focus-visible:outline-blue-600 rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
@click="generateKey">
<span class="inline-flex place-items-center gap-1">
<KeyIcon v-if="!loading" class="w-5 h-5 mr-1" />
<InlineLoadingCircle v-else class="mr-1" />
Expand All @@ -87,6 +87,7 @@
<div v-if="response && response !== ''" class="mt-6 border p-4 rounded-2xl">
<p class="text-base font-semibold">Response</p>
<div

class="mt-1 space-y-6 border-gray-900/10 pb-6 sm:space-y-0 sm:divide-y sm:divide-gray-900/10 sm:border-t sm:pb-0">
<p class="mt-2 flex items-center bg-green-100 p-3 rounded-xl overflow-x-scroll">
<CheckIcon class="w-5 h-5 mr-1 text-green-600" />
Expand Down Expand Up @@ -188,36 +189,45 @@ const currentWallet = useCurrentWallet();
async function generateKey() {
const body = {
backend: data.keyGenerationRequest.type,
backend: data.keyGenerationRequest.type.includes("aws") ? "aws" : data.keyGenerationRequest.type,
keyType: data.type,
config: {
// If AWS, wrap config keys in an 'auth' object, otherwise leave them in the config
...(data.keyGenerationRequest.type.includes("aws")
? {
auth: {
accessKeyId: data.keyGenerationRequest.config.accessKeyId,
secretAccessKey: data.keyGenerationRequest.config.secretAccessKey,
region: data.keyGenerationRequest.config.region,
},
}
: {
// If not AWS, keep keys in the config directly
...data.keyGenerationRequest.config,
}),
...(data.keyGenerationRequest.type === "aws-access-key"
? {
auth: {
accessKeyId: data.keyGenerationRequest.config.accessKeyId,
secretAccessKey: data.keyGenerationRequest.config.secretAccessKey,
region: data.keyGenerationRequest.config.region,
},
}
: data.keyGenerationRequest.type === "aws-role-name"
? {
auth: {
roleName: data.keyGenerationRequest.config.roleName,
region: data.keyGenerationRequest.config.region,
},
}
: {
// If not AWS, keep keys in the config directly
...data.keyGenerationRequest.config,
}),
},
};
loading.value = true;
try {
response.value = await $fetch(
`/wallet-api/wallet/${currentWallet.value}/keys/generate`,
{
method: "POST",
body: JSON.stringify(body), // Ensure the body is a JSON string
headers: {
"Content-Type": "application/json",
},
}
`/wallet-api/wallet/${currentWallet.value}/keys/generate`,
{
method: "POST",
body: JSON.stringify(body), // Ensure the body is a JSON string
headers: {
"Content-Type": "application/json",
},
}
);
} catch (e: any) {
console.error("Error generating key:", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ actual class OCIKey actual constructor(
keyVersion = getKeyVersion(kmsManagementClient, id),
)

override suspend fun deleteKey(): Boolean {
TODO("Not yet implemented")
}


actual companion object {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,15 @@ abstract class Key {
@Throws(Exception::class)
abstract suspend fun getMeta(): KeyMeta


@JvmBlocking
@JvmAsync
@JsPromise
@JsExport.Ignore
@Throws(Exception::class)
abstract suspend fun deleteKey(): Boolean


@JvmBlocking
@JvmAsync
@JsPromise
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,40 @@ class AWSKey(
@JsExport.Ignore
override suspend fun getMeta(): AwsKeyMeta = AwsKeyMeta(getKeyId())

@JvmBlocking
@JvmAsync
@JsPromise
@JsExport.Ignore
override suspend fun deleteKey(): Boolean {
val body = """
{
"KeyId":"$id",
"PendingWindowInDays":7
}
""".trimIndent().trimMargin()
val headers = buildSigV4Headers(
HttpMethod.Post,
payload = body,
config = config
)

val awsKmsUrl = "kms.${config.auth.region}.amazonaws.com"

logger.debug { "Calling AWS KMS ($awsKmsUrl) - TrentService.ScheduleKeyDeletion" }

val response = client.post("https://$awsKmsUrl/") {
headers {
headers.forEach { (key, value) -> append(key, value) } // Append each SigV4 header to the request
append(HttpHeaders.Host, awsKmsUrl)
append("X-Amz-Target", "TrentService.ScheduleKeyDeletion") // Specific KMS action for CreateKey
}
setBody(body)
}
logger.debug { "Key $id scheduled for deletion" }
return response.status == HttpStatusCode.OK
}



companion object : AWSKeyCreator {
val client = HttpClient()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ expect class JWKKey(jwk: String?, _keyId: String? = null) : Key {
override suspend fun getPublicKey(): JWKKey
override suspend fun getPublicKeyRepresentation(): ByteArray
override suspend fun getMeta(): JwkKeyMeta
override suspend fun deleteKey(): Boolean


override val hasPrivateKey: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ class OCIKeyRestApi(
keyVersion = getKeyVersion(id, vaultKeyId, config.managementEndpoint, config.signingKeyPem)
)

@JvmBlocking
@JvmAsync
@JsPromise
@JsExport.Ignore
override suspend fun deleteKey(): Boolean {
TODO("Not yet implemented")
}

companion object {

private fun keyTypeToOciKeyMapping(type: KeyType) = when (type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,14 @@ class TSEKey(
@JsExport.Ignore
override suspend fun getMeta(): TseKeyMeta = TseKeyMeta(getKeyId())

@JvmBlocking
@JvmAsync
@JsPromise
@JsExport.Ignore
override suspend fun deleteKey(): Boolean {
TODO("Not yet implemented")
}

override fun toString(): String = "[TSE ${keyType.name} key @ $server]"

@JvmBlocking
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class AWSKeyTest {

println("Testing sign & verify JWS (payload: ${Config.payloadJWS})...")
awsTestSignJws()


println("Testing key deletion...")
awsTestDeleteKey()
}
}

Expand Down Expand Up @@ -111,4 +115,12 @@ class AWSKeyTest {
assertEquals(payloadJWS, verified.getOrThrow(), "JWS payload mismatch after verification")
}
}

private suspend fun awsTestDeleteKey() {
keys.forEach { key ->
println("Deleting key: ${key.getKeyId()}")
key.deleteKey()
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ actual class JWKKey actual constructor(
@JsExport.Ignore
actual override suspend fun getMeta(): JwkKeyMeta = JwkKeyMeta(getKeyId())

@JsExport.Ignore
actual override suspend fun deleteKey() = true

actual override val keyType: KeyType
get() {
val k = _internalKey.asDynamic()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ actual class JWKKey actual constructor(
}

actual override suspend fun getMeta(): JwkKeyMeta = JwkKeyMeta(getKeyId())
actual override suspend fun deleteKey() = true

actual override suspend fun exportJWK(): String = _internalJwk.toJSONString()

Expand Down
Loading

0 comments on commit 013d3ac

Please sign in to comment.