use basil_proto::broker::v1 as pb;
use tokio::runtime::Runtime;
use crate::Client;
use crate::client::{
AgentExplanation, AgentHealth, AgentReadiness, AgentReload, AgentRevocation, AgentStatus,
AllowedNatsSigner, ImportEntry, IssuedCertificate, KeyHandle, MintedJwt, NatsJwtValidation,
NatsUserPermissions, SecretValue, SignNatsJwtOptions,
};
use crate::constants::DEFAULT_CONN_TIMEOUT;
use crate::error::Result;
use crate::proto::{AeadAlgorithm, CiphertextEnvelope, KeyMaterial, KeyType};
pub struct BlockingClient {
runtime: Runtime,
inner: Client,
}
impl BlockingClient {
pub fn connect(path: &str) -> Result<Self> {
Self::connect_with_timeout(path, DEFAULT_CONN_TIMEOUT)
}
pub fn connect_with_timeout(path: &str, default_timeout: u64) -> Result<Self> {
let runtime = Runtime::new()?;
let inner = runtime.block_on(Client::connect_with_timeout(path, default_timeout))?;
Ok(Self { runtime, inner })
}
pub fn new_key(&mut self, key_id: &str, key_type: KeyType) -> Result<KeyHandle> {
self.runtime.block_on(self.inner.new_key(key_id, key_type))
}
pub fn import(
&mut self,
key_id: &str,
key_type: KeyType,
material: KeyMaterial,
) -> Result<KeyHandle> {
self.runtime
.block_on(self.inner.import(key_id, key_type, material))
}
pub fn import_set(&mut self, entries: Vec<ImportEntry>) -> Result<Vec<KeyHandle>> {
self.runtime.block_on(self.inner.import_set(entries))
}
pub fn sign(&mut self, key_id: &str, message: &[u8]) -> Result<Vec<u8>> {
self.runtime.block_on(self.inner.sign(key_id, message))
}
pub fn verify(&mut self, key_id: &str, message: &[u8], signature: &[u8]) -> Result<bool> {
self.runtime
.block_on(self.inner.verify(key_id, message, signature))
}
pub fn get_public_key(
&mut self,
key_id: &str,
version: Option<u32>,
) -> Result<pb::GetPublicKeyResponse> {
self.runtime
.block_on(self.inner.get_public_key(key_id, version))
}
pub fn encrypt(
&mut self,
key_id: &str,
algorithm: AeadAlgorithm,
plaintext: &[u8],
aad: Option<&[u8]>,
) -> Result<CiphertextEnvelope> {
self.runtime
.block_on(self.inner.encrypt(key_id, algorithm, plaintext, aad))
}
pub fn decrypt(
&mut self,
key_id: &str,
envelope: CiphertextEnvelope,
aad: Option<&[u8]>,
) -> Result<Vec<u8>> {
self.runtime
.block_on(self.inner.decrypt(key_id, envelope, aad))
}
pub fn wrap_envelope(
&mut self,
key_id: &str,
kem_algorithm: pb::KemAlgorithm,
envelope_algorithm: pb::EnvelopeAlgorithm,
plaintext: &[u8],
aad: Option<&[u8]>,
) -> Result<pb::KemEnvelope> {
self.runtime.block_on(self.inner.wrap_envelope(
key_id,
kem_algorithm,
envelope_algorithm,
plaintext,
aad,
))
}
pub fn unwrap_envelope(
&mut self,
key_id: &str,
envelope: pb::KemEnvelope,
aad: Option<&[u8]>,
) -> Result<Vec<u8>> {
self.runtime
.block_on(self.inner.unwrap_envelope(key_id, envelope, aad))
}
pub fn get_secret(&mut self, secret_id: &str, version: Option<u32>) -> Result<SecretValue> {
self.runtime
.block_on(self.inner.get_secret(secret_id, version))
}
pub fn set_secret(&mut self, secret_id: &str, value: &[u8]) -> Result<u32> {
self.runtime
.block_on(self.inner.set_secret(secret_id, value))
}
pub fn rotate_secret(&mut self, secret_id: &str) -> Result<u32> {
self.runtime.block_on(self.inner.rotate_secret(secret_id))
}
pub fn list_catalog(&mut self, prefix: Option<&str>) -> Result<Vec<pb::CatalogEntry>> {
self.runtime.block_on(self.inner.list_catalog(prefix))
}
pub fn mint_jwt(
&mut self,
key_id: &str,
sub: &str,
ttl_secs: Option<u64>,
claims: serde_json::Value,
) -> Result<MintedJwt> {
self.runtime
.block_on(self.inner.mint_jwt(key_id, sub, ttl_secs, claims))
}
pub fn mint_nats_user(
&mut self,
key_id: &str,
subject_user_nkey: &str,
issuer_account: Option<&str>,
name: &str,
ttl_secs: Option<u64>,
permissions: NatsUserPermissions,
) -> Result<String> {
self.runtime.block_on(self.inner.mint_nats_user(
key_id,
subject_user_nkey,
issuer_account,
name,
ttl_secs,
permissions,
))
}
pub fn mint_nats_account(
&mut self,
signing_key_id: &str,
subject_account_nkey: &str,
name: &str,
signing_keys: &[String],
expires_in_secs: Option<u64>,
) -> Result<String> {
self.runtime.block_on(self.inner.mint_nats_account(
signing_key_id,
subject_account_nkey,
name,
signing_keys,
expires_in_secs,
))
}
#[allow(clippy::too_many_arguments)]
pub fn mint_nats_operator(
&mut self,
signing_key_id: &str,
subject_operator_nkey: Option<&str>,
name: &str,
signing_keys: &[String],
account_server_url: Option<&str>,
system_account: Option<&str>,
expires_in_secs: Option<u64>,
) -> Result<String> {
self.runtime.block_on(self.inner.mint_nats_operator(
signing_key_id,
subject_operator_nkey,
name,
signing_keys,
account_server_url,
system_account,
expires_in_secs,
))
}
pub fn mint_nats_signer(
&mut self,
signing_key_id: &str,
subject_nkey: &str,
name: &str,
expires_in_secs: Option<u64>,
) -> Result<String> {
self.runtime.block_on(self.inner.mint_nats_signer(
signing_key_id,
subject_nkey,
name,
expires_in_secs,
))
}
pub fn mint_nats_server(
&mut self,
signing_key_id: &str,
subject_server_nkey: &str,
name: &str,
expires_in_secs: Option<u64>,
) -> Result<String> {
self.runtime.block_on(self.inner.mint_nats_server(
signing_key_id,
subject_server_nkey,
name,
expires_in_secs,
))
}
pub fn mint_nats_curve(
&mut self,
signing_key_id: &str,
subject_curve_nkey: &str,
name: &str,
expires_in_secs: Option<u64>,
) -> Result<String> {
self.runtime.block_on(self.inner.mint_nats_curve(
signing_key_id,
subject_curve_nkey,
name,
expires_in_secs,
))
}
pub fn encrypt_nats_curve(
&mut self,
key_id: &str,
recipient_public_xkey: &str,
plaintext: &[u8],
) -> Result<Vec<u8>> {
self.runtime.block_on(self.inner.encrypt_nats_curve(
key_id,
recipient_public_xkey,
plaintext,
))
}
pub fn decrypt_nats_curve(
&mut self,
key_id: &str,
sender_public_xkey: &str,
ciphertext: &[u8],
) -> Result<Vec<u8>> {
self.runtime.block_on(
self.inner
.decrypt_nats_curve(key_id, sender_public_xkey, ciphertext),
)
}
pub fn sign_nats_jwt(
&mut self,
key_id: &str,
claims: impl serde::Serialize,
options: SignNatsJwtOptions,
) -> Result<MintedJwt> {
self.runtime
.block_on(self.inner.sign_nats_jwt(key_id, claims, options))
}
pub fn sign_nats_jwt_json(
&mut self,
key_id: &str,
claims_json: impl Into<Vec<u8>>,
options: SignNatsJwtOptions,
) -> Result<MintedJwt> {
self.runtime
.block_on(self.inner.sign_nats_jwt_json(key_id, claims_json, options))
}
pub fn validate_nats_jwt(
&mut self,
jwt: &str,
allowed_signers: impl IntoIterator<Item = AllowedNatsSigner>,
expected_type: Option<pb::NatsJwtType>,
) -> Result<NatsJwtValidation> {
self.runtime.block_on(
self.inner
.validate_nats_jwt(jwt, allowed_signers, expected_type),
)
}
pub fn issue_certificate(
&mut self,
issuer_key_id: &str,
common_name: &str,
dns_sans: &[String],
ip_sans: &[String],
ttl_secs: u64,
) -> Result<IssuedCertificate> {
self.runtime.block_on(self.inner.issue_certificate(
issuer_key_id,
common_name,
dns_sans,
ip_sans,
ttl_secs,
))
}
pub fn status(&mut self) -> Result<AgentStatus> {
self.runtime.block_on(self.inner.status())
}
pub fn health(&mut self) -> Result<AgentHealth> {
self.runtime.block_on(self.inner.health())
}
pub fn readiness(&mut self) -> Result<AgentReadiness> {
self.runtime.block_on(self.inner.readiness())
}
pub fn reload(&mut self, check: bool) -> Result<AgentReload> {
self.runtime.block_on(self.inner.reload(check))
}
pub fn explain(&mut self, subject: &str, op: &str, key: &str) -> Result<AgentExplanation> {
self.runtime.block_on(self.inner.explain(subject, op, key))
}
pub fn revoke(
&mut self,
trust_domain: &str,
jti: &str,
expires_at_unix: u64,
) -> Result<AgentRevocation> {
self.runtime
.block_on(self.inner.revoke(trust_domain, jti, expires_at_unix))
}
}