diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index db623b6..80e8943 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,6 +11,7 @@ jobs: name: Release Build runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [ ubuntu-latest, @@ -23,12 +24,28 @@ jobs: ] steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Toolchain uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.toolchain }} + - name: Install vcpkg Packages + if: matrix.os == 'windows-latest' + uses: johnwason/vcpkg-action@v6 + id: vcpkg + with: + pkgs: libsodium + triplet: x64-windows-release + token: ${{ github.token }} + github-binarycache: true + + - name: Make Release Windows + if: matrix.os == 'windows-latest' + run: |- + $env:SODIUM_LIB_DIR="$(pwd)\vcpkg\packages\libsodium_x64-windows-release\lib" + make release + - name: Make Release run: make release diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index a952965..38d89c3 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -11,6 +11,7 @@ jobs: name: Static Analysis runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [ ubuntu-latest, @@ -21,7 +22,7 @@ jobs: ] steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Toolchain uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd98785..62c8f88 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,6 +11,7 @@ jobs: name: Test runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [ ubuntu-latest, @@ -23,12 +24,29 @@ jobs: ] steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Toolchain uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.toolchain }} + - name: Install vcpkg Packages + if: matrix.os == 'windows-latest' + uses: johnwason/vcpkg-action@v6 + id: vcpkg + with: + pkgs: libsodium + triplet: x64-windows-release + token: ${{ github.token }} + github-binarycache: true + + - name: Make Test Windows + if: matrix.os == 'windows-latest' + run: |- + $env:SODIUM_LIB_DIR="$(pwd)\vcpkg\packages\libsodium_x64-windows-release\lib" + make test + - name: Make Test + if: matrix.os != 'windows-latest' run: make test diff --git a/crates/lair_keystore/CHANGELOG.md b/crates/lair_keystore/CHANGELOG.md index 62c8de4..60243f3 100644 --- a/crates/lair_keystore/CHANGELOG.md +++ b/crates/lair_keystore/CHANGELOG.md @@ -1 +1,9 @@ +## 0.4.1 + +- Add a way to migrate unencrypted databases to encrypted by providing an environment variable `LAIR_MIGRATE_UNENCRYPTED="true"`, Lair will detect databases which can't be opened and attempt migration. #121 + +# 0.4.0 + +- pin serde and rmp-serde #119 + ## 0.0.2 diff --git a/crates/lair_keystore/src/lib.rs b/crates/lair_keystore/src/lib.rs index f902596..ad75d60 100644 --- a/crates/lair_keystore/src/lib.rs +++ b/crates/lair_keystore/src/lib.rs @@ -54,6 +54,8 @@ include!(concat!(env!("OUT_DIR"), "/ver.rs")); /// Re-exported dependencies. pub mod dependencies { + // Not sure why Clippy picks this up as unused, it's exported to be used elsewhere + #[allow(unused_imports)] pub use hc_seed_bundle::dependencies::*; pub use lair_keystore_api; pub use lair_keystore_api::dependencies::*; @@ -75,6 +77,3 @@ pub mod store_sqlite; #[doc(inline)] pub use store_sqlite::create_sql_pool_factory; - -#[cfg(test)] -mod server_test; diff --git a/crates/lair_keystore/src/store_sqlite.rs b/crates/lair_keystore/src/store_sqlite.rs index 9ab18c5..1c82a70 100644 --- a/crates/lair_keystore/src/store_sqlite.rs +++ b/crates/lair_keystore/src/store_sqlite.rs @@ -111,20 +111,18 @@ impl SqlCon { /// extension trait for execute that we don't care about results trait ExecExt { - fn execute_optional
(&self, sql: &str, params: P) -> LairResult<()> + fn execute_optional
(&self, sql: &str, params: P) -> rusqlite::Result<()> where P: rusqlite::Params; } impl ExecExt for rusqlite::Connection { - fn execute_optional
(&self, sql: &str, params: P) -> LairResult<()> + fn execute_optional
(&self, sql: &str, params: P) -> rusqlite::Result<()>
where
P: rusqlite::Params,
{
use rusqlite::OptionalExtension;
- self.query_row(sql, params, |_| Ok(()))
- .optional()
- .map_err(one_err::OneErr::new)?;
+ self.query_row(sql, params, |_| Ok(())).optional()?;
Ok(())
}
}
@@ -163,18 +161,38 @@ impl SqlPool {
// initialize the sqlcipher key pragma
let key_pragma = secure_write_key_pragma(dbk_secret)?;
- // open a single write connection to the database
- let mut write_con = rusqlite::Connection::open_with_flags(
- &path,
- OpenFlags::SQLITE_OPEN_READ_WRITE
- | OpenFlags::SQLITE_OPEN_CREATE
- | OpenFlags::SQLITE_OPEN_NO_MUTEX
- | OpenFlags::SQLITE_OPEN_URI,
- )
- .map_err(one_err::OneErr::new)?;
-
- // set generic pragmas
- set_pragmas(&write_con, key_pragma.clone())?;
+ let mut write_con =
+ match create_configured_db_connection(&path, key_pragma.clone()) {
+ Ok(con) => con,
+ Err(
+ err @ rusqlite::Error::SqliteFailure(
+ rusqlite::ffi::Error {
+ code: rusqlite::ffi::ErrorCode::NotADatabase,
+ ..
+ },
+ ..,
+ ),
+ ) => {
+ if "true"
+ == std::env::var("LAIR_MIGRATE_UNENCRYPTED")
+ .unwrap_or_default()
+ .as_str()
+ {
+ encrypt_unencrypted_database(
+ &path,
+ key_pragma.clone(),
+ )?;
+ create_configured_db_connection(
+ &path,
+ key_pragma.clone(),
+ )
+ .map_err(one_err::OneErr::new)?
+ } else {
+ return Err(one_err::OneErr::new(err));
+ }
+ }
+ Err(e) => return Err(one_err::OneErr::new(e)),
+ };
// only set WAL mode on the first write connection
// it's a slow operation, and not needed on subsequent connections.
@@ -213,7 +231,8 @@ impl SqlPool {
.map_err(one_err::OneErr::new)?;
// set generic pragmas
- set_pragmas(&read_con, key_pragma.clone())?;
+ set_pragmas(&read_con, key_pragma.clone())
+ .map_err(one_err::OneErr::new)?;
*rc_mut = Some(read_con);
}
@@ -289,6 +308,27 @@ impl SqlPool {
}
}
+fn create_configured_db_connection(
+ path: &std::path::PathBuf,
+ key_pragma: BufRead,
+) -> rusqlite::Result