forge_connectors/
vault.rs1pub mod client;
11pub mod crypto;
12pub mod models;
13
14pub use client::VaultClient;
15pub use crypto::Unlocked;
16pub use models::{
17 AttachmentMeta, Folder, Organization, Prelogin, Profile, SyncData, TokenResponse, TwoFactorCode,
18};
19
20use thiserror::Error;
21
22#[derive(Debug, Error)]
26pub enum VaultError {
27 #[error("request failed: {}", http_class(.0))]
30 Http(#[from] reqwest::Error),
31 #[error("no unlocked key for organization {0}")]
32 MissingKey(String),
33 #[error("the account has no private key, so its RSA-wrapped items cannot be opened")]
34 MissingPrivateKey,
35 #[error("the account's keys changed while unlocked; unlock again")]
36 KeyRotated,
37 #[error("the account's user key could not be verified; unlock again")]
38 KeyUnverifiable,
39 #[error("invalid request: {0}")]
40 InvalidInput(String),
41 #[error("refused attachment URL: {0}")]
42 InvalidUrl(String),
43 #[error("the attachment is {size} bytes, over the {cap} byte cap")]
44 AttachmentTooLarge { size: u64, cap: u64 },
45 #[error("vault is locked")]
46 Locked,
47 #[error("unauthorized")]
48 Unauthorized,
49 #[error("forbidden: {0}")]
50 Forbidden(String),
51 #[error("not found: {0}")]
52 NotFound(String),
53 #[error("rate limited; retry after {retry_after:?} seconds")]
54 RateLimited { retry_after: Option<u64> },
55 #[error("API error {status}: {body}")]
56 Api { status: u16, body: String },
57 #[error("crypto error: {0}")]
58 Crypto(#[from] anyhow::Error),
59 #[error("invalid response: {0}")]
60 InvalidResponse(String),
61}
62
63fn http_class(error: &reqwest::Error) -> &'static str {
64 if error.is_timeout() {
65 "timed out"
66 } else if error.is_connect() {
67 "could not connect"
68 } else if error.is_body() {
69 "the response body could not be read"
70 } else if error.is_decode() {
71 "the response could not be decoded"
72 } else if error.is_request() {
73 "the request could not be sent"
74 } else {
75 "the request failed"
76 }
77}