[WIP] Encryption for secure values (#183)

This commit is contained in:
Gregory Schier
2025-04-15 07:18:26 -07:00
committed by GitHub
parent e114a85c39
commit 2e55a1bd6d
208 changed files with 4063 additions and 28698 deletions

View File

@@ -3,10 +3,11 @@ use crate::models::HttpRequestIden::{
Authentication, AuthenticationType, Body, BodyType, CreatedAt, Description, FolderId, Headers,
Method, Name, SortPriority, UpdatedAt, Url, UrlParameters, WorkspaceId,
};
use crate::util::{generate_prefixed_id, UpdateSource};
use crate::util::{UpdateSource, generate_prefixed_id};
use chrono::{NaiveDateTime, Utc};
use rusqlite::Row;
use sea_query::{enum_def, IntoIden, IntoTableRef, SimpleExpr};
use sea_query::Order::Desc;
use sea_query::{IntoColumnRef, IntoIden, IntoTableRef, Order, SimpleExpr, enum_def};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::collections::BTreeMap;
@@ -124,6 +125,10 @@ impl UpsertModelInfo for Settings {
panic!("Settings does not have unique IDs")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(SettingsIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -209,6 +214,7 @@ pub struct Workspace {
pub updated_at: NaiveDateTime,
pub name: String,
pub description: String,
pub encryption_key_challenge: Option<String>,
// Settings
#[serde(default = "default_true")]
@@ -231,6 +237,10 @@ impl UpsertModelInfo for Workspace {
generate_prefixed_id("wk")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(WorkspaceIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -245,6 +255,7 @@ impl UpsertModelInfo for Workspace {
(UpdatedAt, upsert_date(source, self.updated_at)),
(Name, self.name.trim().into()),
(Description, self.description.into()),
(EncryptionKeyChallenge, self.encryption_key_challenge.into()),
(SettingFollowRedirects, self.setting_follow_redirects.into()),
(SettingRequestTimeout, self.setting_request_timeout.into()),
(SettingValidateCertificates, self.setting_validate_certificates.into()),
@@ -256,6 +267,7 @@ impl UpsertModelInfo for Workspace {
WorkspaceIden::UpdatedAt,
WorkspaceIden::Name,
WorkspaceIden::Description,
WorkspaceIden::EncryptionKeyChallenge,
WorkspaceIden::SettingRequestTimeout,
WorkspaceIden::SettingFollowRedirects,
WorkspaceIden::SettingRequestTimeout,
@@ -274,6 +286,7 @@ impl UpsertModelInfo for Workspace {
updated_at: row.get("updated_at")?,
name: row.get("name")?,
description: row.get("description")?,
encryption_key_challenge: row.get("encryption_key_challenge")?,
setting_follow_redirects: row.get("setting_follow_redirects")?,
setting_request_timeout: row.get("setting_request_timeout")?,
setting_validate_certificates: row.get("setting_validate_certificates")?,
@@ -281,16 +294,11 @@ impl UpsertModelInfo for Workspace {
}
}
impl Workspace {
pub fn new(name: String) -> Self {
Self {
name,
model: "workspace".to_string(),
setting_validate_certificates: true,
setting_follow_redirects: true,
..Default::default()
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
#[serde(default, rename_all = "camelCase")]
#[ts(export, export_to = "gen_models.ts")]
pub struct EncryptedKey {
pub encrypted_key: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
@@ -304,6 +312,7 @@ pub struct WorkspaceMeta {
pub workspace_id: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
pub encryption_key: Option<EncryptedKey>,
pub setting_sync_dir: Option<String>,
}
@@ -320,6 +329,10 @@ impl UpsertModelInfo for WorkspaceMeta {
generate_prefixed_id("wm")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(WorkspaceMetaIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -333,6 +346,7 @@ impl UpsertModelInfo for WorkspaceMeta {
(CreatedAt, upsert_date(source, self.created_at)),
(UpdatedAt, upsert_date(source, self.updated_at)),
(WorkspaceId, self.workspace_id.into()),
(EncryptionKey, self.encryption_key.map(|e| serde_json::to_string(&e).unwrap()).into()),
(SettingSyncDir, self.setting_sync_dir.into()),
])
}
@@ -340,6 +354,7 @@ impl UpsertModelInfo for WorkspaceMeta {
fn update_columns() -> Vec<impl IntoIden> {
vec![
WorkspaceMetaIden::UpdatedAt,
WorkspaceMetaIden::EncryptionKey,
WorkspaceMetaIden::SettingSyncDir,
]
}
@@ -348,12 +363,14 @@ impl UpsertModelInfo for WorkspaceMeta {
where
Self: Sized,
{
let encryption_key: Option<String> = row.get("encryption_key")?;
Ok(Self {
id: row.get("id")?,
workspace_id: row.get("workspace_id")?,
model: row.get("model")?,
created_at: row.get("created_at")?,
updated_at: row.get("updated_at")?,
encryption_key: encryption_key.map(|e| serde_json::from_str(&e).unwrap()),
setting_sync_dir: row.get("setting_sync_dir")?,
})
}
@@ -413,6 +430,10 @@ impl UpsertModelInfo for CookieJar {
generate_prefixed_id("cj")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(CookieJarIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -486,6 +507,10 @@ impl UpsertModelInfo for Environment {
generate_prefixed_id("ev")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(EnvironmentIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -575,6 +600,10 @@ impl UpsertModelInfo for Folder {
generate_prefixed_id("fl")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(FolderIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -673,7 +702,7 @@ pub struct HttpRequest {
#[serde(default = "default_http_method")]
pub method: String,
pub name: String,
pub sort_priority: f32,
pub sort_priority: f64,
pub url: String,
pub url_parameters: Vec<HttpUrlParameter>,
}
@@ -691,6 +720,10 @@ impl UpsertModelInfo for HttpRequest {
generate_prefixed_id("rq")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(HttpResponseIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.to_string()
}
@@ -745,21 +778,21 @@ impl UpsertModelInfo for HttpRequest {
Ok(Self {
id: r.get("id")?,
model: r.get("model")?,
sort_priority: r.get("sort_priority")?,
workspace_id: r.get("workspace_id")?,
created_at: r.get("created_at")?,
updated_at: r.get("updated_at")?,
url: r.get("url")?,
url_parameters: serde_json::from_str(url_parameters.as_str()).unwrap_or_default(),
method: r.get("method")?,
authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(),
authentication_type: r.get("authentication_type")?,
body: serde_json::from_str(body.as_str()).unwrap_or_default(),
body_type: r.get("body_type")?,
description: r.get("description")?,
authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(),
authentication_type: r.get("authentication_type")?,
headers: serde_json::from_str(headers.as_str()).unwrap_or_default(),
folder_id: r.get("folder_id")?,
headers: serde_json::from_str(headers.as_str()).unwrap_or_default(),
method: r.get("method")?,
name: r.get("name")?,
sort_priority: r.get("sort_priority")?,
url: r.get("url")?,
url_parameters: serde_json::from_str(url_parameters.as_str()).unwrap_or_default(),
})
}
}
@@ -814,6 +847,10 @@ impl UpsertModelInfo for WebsocketConnection {
generate_prefixed_id("wc")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(WebsocketConnectionIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -924,6 +961,10 @@ impl UpsertModelInfo for WebsocketRequest {
generate_prefixed_id("wr")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(WebsocketRequestIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1045,6 +1086,10 @@ impl UpsertModelInfo for WebsocketEvent {
generate_prefixed_id("we")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(WebsocketEventIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1158,6 +1203,10 @@ impl UpsertModelInfo for HttpResponse {
generate_prefixed_id("rs")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(HttpResponseIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1286,6 +1335,10 @@ impl UpsertModelInfo for GrpcRequest {
generate_prefixed_id("gr")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(GrpcRequestIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1409,6 +1462,10 @@ impl UpsertModelInfo for GrpcConnection {
generate_prefixed_id("gc")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(GrpcConnectionIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1525,6 +1582,10 @@ impl UpsertModelInfo for GrpcEvent {
generate_prefixed_id("ge")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(GrpcEventIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1612,6 +1673,10 @@ impl UpsertModelInfo for Plugin {
generate_prefixed_id("pg")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(PluginIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1690,6 +1755,10 @@ impl UpsertModelInfo for SyncState {
generate_prefixed_id("ss")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(SyncStateIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1769,6 +1838,10 @@ impl UpsertModelInfo for KeyValue {
generate_prefixed_id("kv")
}
fn order_by() -> (impl IntoColumnRef, Order) {
(KeyValueIden::CreatedAt, Desc)
}
fn get_id(&self) -> String {
self.id.clone()
}
@@ -1919,13 +1992,18 @@ impl<'de> Deserialize<'de> for AnyModel {
Some(m) if m == "key_value" => AnyModel::KeyValue(fv(value).unwrap()),
Some(m) if m == "plugin" => AnyModel::Plugin(fv(value).unwrap()),
Some(m) if m == "settings" => AnyModel::Settings(fv(value).unwrap()),
Some(m) if m == "websocket_connection" => AnyModel::WebsocketConnection(fv(value).unwrap()),
Some(m) if m == "websocket_connection" => {
AnyModel::WebsocketConnection(fv(value).unwrap())
}
Some(m) if m == "websocket_event" => AnyModel::WebsocketEvent(fv(value).unwrap()),
Some(m) if m == "websocket_request" => AnyModel::WebsocketRequest(fv(value).unwrap()),
Some(m) if m == "workspace" => AnyModel::Workspace(fv(value).unwrap()),
Some(m) if m == "workspace_meta" => AnyModel::WorkspaceMeta(fv(value).unwrap()),
Some(m) => {
return Err(serde::de::Error::custom(format!("Failed to deserialize AnyModel {}", m)));
return Err(serde::de::Error::custom(format!(
"Failed to deserialize AnyModel {}",
m
)));
}
None => {
return Err(serde::de::Error::custom("Missing or invalid model"));
@@ -1963,6 +2041,7 @@ pub trait UpsertModelInfo {
fn table_name() -> impl IntoTableRef;
fn id_column() -> impl IntoIden + Eq + Clone;
fn generate_id() -> String;
fn order_by() -> (impl IntoColumnRef, Order);
fn get_id(&self) -> String;
fn insert_values(
self,