diff --git a/Cargo.lock b/Cargo.lock index 8bdf64e..1c7396d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -234,9 +234,9 @@ dependencies = [ "gpgme", "indoc", "josekit", + "migrations", "pgp", "sea-orm", - "sea-orm-migration", "thiserror", "tokio", ] @@ -1806,6 +1806,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "migrations" +version = "0.1.0" +dependencies = [ + "sea-orm-migration", + "tokio", +] + [[package]] name = "mime" version = "0.3.17" @@ -2488,6 +2496,20 @@ dependencies = [ "subtle", ] +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted", + "windows-sys 0.48.0", +] + [[package]] name = "ripemd" version = "0.1.3" @@ -2590,6 +2612,36 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.16" @@ -2626,6 +2678,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sea-bae" version = "0.2.0" @@ -2641,9 +2703,9 @@ dependencies = [ [[package]] name = "sea-orm" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cbf88748872fa54192476d6d49d0775e208566a72656e267e45f6980b926c8d" +checksum = "6632f499b80cc6aaa781b302e4c9fae663e0e3dcf2640e9d80034d5b10731efe" dependencies = [ "async-stream", "async-trait", @@ -2669,9 +2731,9 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f17eb697616be2f3e4ea3b468a44cfb6848750dec522fdef4caa44bf5a02beb" +checksum = "465ea2308d4716837e9af4a2cff8e14c28135867a580bb93e9e03d408a3a6afb" dependencies = [ "chrono", "clap", @@ -2686,9 +2748,9 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0dbc880d47aa53c6a572e39c99402c7fad59b50766e51e0b0fc1306510b0555" +checksum = "ec13bfb4c4aef208f68dbea970dd40d13830c868aa8dcb4e106b956e6bb4f2fa" dependencies = [ "heck", "proc-macro2", @@ -2700,9 +2762,9 @@ dependencies = [ [[package]] name = "sea-orm-migration" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42807e13d38edd4cc1f9cbb370df898d43a9a143f6161dcdb8424a6de002def" +checksum = "ac734b6e5610c2764056cc8495fbc293cd1c8ebe084fdfb74c3b0cdaaff9bb92" dependencies = [ "async-trait", "clap", @@ -3061,11 +3123,12 @@ dependencies = [ "indexmap", "log", "memchr", - "native-tls", "once_cell", "paste", "percent-encoding", "rust_decimal", + "rustls", + "rustls-pemfile", "serde", "serde_json", "sha2", @@ -3078,6 +3141,7 @@ dependencies = [ "tracing", "url", "uuid", + "webpki-roots", ] [[package]] @@ -3442,9 +3506,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -3660,6 +3724,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.0" @@ -3812,6 +3882,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "whoami" version = "1.4.1" diff --git a/Cargo.toml b/Cargo.toml index a159fcc..337ad6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,8 +22,7 @@ anstyle = "1.0.4" dialoguer = { version = "0.11.0", features = ["password"] } argon2 = { version = "0.5.3", features = ["std"] } data-encoding = "2.5.0" -sea-orm = { version = "0.12.12", features = ["sqlx-sqlite", "runtime-tokio-native-tls"] } -sea-orm-migration = "0.12.12" +sea-orm = { version = "0.12.12", features = ["sqlx-sqlite", "runtime-tokio-rustls"] } async-trait = "0.1.77" tokio = "1.35.1" clap-stdin = "0.4.0" @@ -32,6 +31,7 @@ pgp = { version = "0.10.2", optional = true } josekit = { version = "0.8.5", optional = true } elliptic-curve = { version = "0.13.8", optional = true } aes-gcm = "0.10.3" +migrations = { path = "crates/migrations" } [features] gpg-compat = ["dep:gpgme", "dep:pgp", "dep:josekit", "dep:elliptic-curve"] diff --git a/crates/migrations/Cargo.toml b/crates/migrations/Cargo.toml new file mode 100644 index 0000000..9c76cc0 --- /dev/null +++ b/crates/migrations/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "migrations" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +sea-orm-migration = { version = "0.12.14", features = ["sqlx-sqlite", "runtime-tokio-rustls"] } +tokio = { version = "1.36.0", features = ["rt-multi-thread", "macros"] } diff --git a/crates/migrations/src/lib.rs b/crates/migrations/src/lib.rs new file mode 100644 index 0000000..9651f01 --- /dev/null +++ b/crates/migrations/src/lib.rs @@ -0,0 +1,17 @@ +mod m_20230701_000001_create_keys_table; +mod m_20242801_000002_create_profiles_table; + +use sea_orm_migration::prelude::*; + +pub use sea_orm_migration::{SchemaManager, MigratorTrait}; + +pub struct Migrator; + +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![ + Box::new(m_20230701_000001_create_keys_table::Migration), + Box::new(m_20242801_000002_create_profiles_table::Migration) + ] + } +} diff --git a/src/migrations/m_20230701_000001_create_keys_table.rs b/crates/migrations/src/m_20230701_000001_create_keys_table.rs similarity index 98% rename from src/migrations/m_20230701_000001_create_keys_table.rs rename to crates/migrations/src/m_20230701_000001_create_keys_table.rs index 56931af..bda9a79 100644 --- a/src/migrations/m_20230701_000001_create_keys_table.rs +++ b/crates/migrations/src/m_20230701_000001_create_keys_table.rs @@ -39,7 +39,7 @@ impl MigrationTrait for Migration { } #[derive(Iden)] -enum Keys { +pub enum Keys { Table, Fingerprint, KeyType, diff --git a/crates/migrations/src/m_20242801_000002_create_profiles_table.rs b/crates/migrations/src/m_20242801_000002_create_profiles_table.rs new file mode 100644 index 0000000..19ec781 --- /dev/null +++ b/crates/migrations/src/m_20242801_000002_create_profiles_table.rs @@ -0,0 +1,128 @@ +use sea_orm_migration::prelude::*; + +pub struct Migration; + +impl MigrationName for Migration { + fn name(&self) -> &str { + "m_20242801_000002_create_profiles_table.rs" + } +} + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + // Define how to apply this migration: Create the Keys table. + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager.create_table( + Table::create() + .table(Claims::Table) + .col( + ColumnDef::new(Claims::Id) + .unsigned() + .not_null() + .primary_key() + .auto_increment() + ) + .col( + ColumnDef::new(Claims::Uri) + .string() + .not_null() + ) + .col( + ColumnDef::new(Claims::Profile) + .string_len(26) + .not_null() + ) + .foreign_key( + ForeignKey::create() + .name("fk-claims_profile-profiles_key") + .from(Claims::Table, Claims::Profile) + .to(Profiles::Table, Profiles::Key) + .on_update(ForeignKeyAction::Cascade) + .on_delete(ForeignKeyAction::Cascade) + ) + .to_owned() + ).await?; + + manager.create_table( + Table::create() + .table(Profiles::Table) + .col( + ColumnDef::new(Profiles::Key) + .string_len(26) + .not_null() + .primary_key(), + ) + .foreign_key( + ForeignKey::create() + .name("fk-profiles_key-keys_fingerprint") + .from(Profiles::Table, Profiles::Key) + .to( + super::m_20230701_000001_create_keys_table::Keys::Table, + super::m_20230701_000001_create_keys_table::Keys::Fingerprint + ) + .on_update(ForeignKeyAction::Cascade) + .on_delete(ForeignKeyAction::Restrict) + ) + .col( + ColumnDef::new(Profiles::Name) + .string() + .not_null() + ) + .col( + ColumnDef::new(Profiles::Description) + .string() + .null() + ) + .col( + ColumnDef::new(Profiles::AvatarUrl) + .string() + .null() + ) + .col( + ColumnDef::new(Profiles::Email) + .string() + .null() + ) + .col( + ColumnDef::new(Profiles::Color) + .string_len(7) + .null() + ) + .to_owned() + ).await?; + + Ok(()) + } + + // Define how to rollback this migration: Drop the Keys table. + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Claims::Table).to_owned()) + .await?; + + manager + .drop_table(Table::drop().table(Profiles::Table).to_owned()) + .await?; + + Ok(()) + } +} + +#[derive(Iden)] +pub enum Profiles { + Table, + Key, + Name, + Description, + AvatarUrl, + Email, + Color, +} + +#[derive(Iden)] +pub enum Claims { + Table, + Id, + Uri, + Profile, +} diff --git a/crates/migrations/src/main.rs b/crates/migrations/src/main.rs new file mode 100644 index 0000000..1f3ffee --- /dev/null +++ b/crates/migrations/src/main.rs @@ -0,0 +1,6 @@ +use sea_orm_migration::cli; + +#[tokio::main] +async fn main() { + cli::run_cli(migrations::Migrator).await; +} \ No newline at end of file diff --git a/src/entities/claims.rs b/src/entities/claims.rs new file mode 100644 index 0000000..0d87f8f --- /dev/null +++ b/src/entities/claims.rs @@ -0,0 +1,32 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.12 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "claims")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub uri: String, + pub profile: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::profiles::Entity", + from = "Column::Profile", + to = "super::profiles::Column::Key", + on_update = "Cascade", + on_delete = "Cascade" + )] + Profiles, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Profiles.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/src/entities/keys.rs b/src/entities/keys.rs index b9d2eb1..3104ec6 100644 --- a/src/entities/keys.rs +++ b/src/entities/keys.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.12 use sea_orm::entity::prelude::*; @@ -9,10 +9,20 @@ pub struct Model { pub fingerprint: String, pub key_type: i32, pub alias: String, + #[sea_orm(column_type = "Binary(BlobSize::Blob(None))")] pub cipher_text: Vec, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation {} +pub enum Relation { + #[sea_orm(has_many = "super::profiles::Entity")] + Profiles, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Profiles.def() + } +} impl ActiveModelBehavior for ActiveModel {} diff --git a/src/entities/mod.rs b/src/entities/mod.rs index 37aba69..047aa4d 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -1,5 +1,7 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.12 pub mod prelude; +pub mod claims; pub mod keys; +pub mod profiles; diff --git a/src/entities/prelude.rs b/src/entities/prelude.rs index bf7fa3f..7fe1348 100644 --- a/src/entities/prelude.rs +++ b/src/entities/prelude.rs @@ -1,3 +1,5 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.12 +pub use super::claims::Entity as Claims; pub use super::keys::Entity as Keys; +pub use super::profiles::Entity as Profiles; diff --git a/src/entities/profiles.rs b/src/entities/profiles.rs new file mode 100644 index 0000000..882ec6b --- /dev/null +++ b/src/entities/profiles.rs @@ -0,0 +1,43 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.12 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "profiles")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub key: String, + pub name: String, + pub description: Option, + pub avatar_url: Option, + pub email: Option, + pub color: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::claims::Entity")] + Claims, + #[sea_orm( + belongs_to = "super::keys::Entity", + from = "Column::Key", + to = "super::keys::Column::Fingerprint", + on_update = "Cascade", + on_delete = "Restrict" + )] + Keys, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Claims.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Keys.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/src/main.rs b/src/main.rs index 6020db2..36e65c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ mod commands; mod entities; -mod migrations; use anstyle::{AnsiColor, Color as AnstyleColor, Style as Anstyle}; use anyhow::Context; @@ -10,10 +9,9 @@ use commands::{ keys::{import::KeysImportSubcommands, KeysSubcommands}, AspmSubcommand, }; -use migrations::Migrator; use sea_orm::{Database, DatabaseConnection}; -use sea_orm_migration::{MigratorTrait, SchemaManager}; use thiserror::Error; +use migrations::{Migrator, SchemaManager, MigratorTrait}; use std::path::PathBuf; diff --git a/src/migrations/mod.rs b/src/migrations/mod.rs deleted file mode 100644 index 19b82b1..0000000 --- a/src/migrations/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod m_20230701_000001_create_keys_table; - -use sea_orm_migration::prelude::*; - -pub struct Migrator; - -impl MigratorTrait for Migrator { - fn migrations() -> Vec> { - vec![Box::new(m_20230701_000001_create_keys_table::Migration)] - } -}