Skip to content

Commit 7f6bd80

Browse files
committed
feat!: Add masterkey as credential option
1 parent a6f4589 commit 7f6bd80

File tree

25 files changed

+445
-357
lines changed

25 files changed

+445
-357
lines changed

crates/core/src/commands/init.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
error::RusticResult,
1414
id::Id,
1515
repofile::{ConfigFile, KeyId, configfile::RepositoryId},
16-
repository::Repository,
16+
repository::{Repository, credentials::Credential},
1717
};
1818

1919
/// Initialize a new repository.
@@ -39,10 +39,10 @@ use crate::{
3939
/// A tuple of the key and the config file.
4040
pub(crate) fn init<P, S>(
4141
repo: &Repository<P, S>,
42-
pass: &str,
42+
credentials: &Credential,
4343
key_opts: &KeyOptions,
4444
config_opts: &ConfigOptions,
45-
) -> RusticResult<(Key, KeyId, ConfigFile)> {
45+
) -> RusticResult<(Key, Option<KeyId>, ConfigFile)> {
4646
// Create config first to allow catching errors from here without writing anything
4747
let repo_id = RepositoryId::from(Id::random());
4848
let chunker_poly = random_poly()?;
@@ -54,7 +54,7 @@ pub(crate) fn init<P, S>(
5454
}
5555
config_opts.apply(&mut config)?;
5656

57-
let (key, key_id) = init_with_config(repo, pass, key_opts, &config)?;
57+
let (key, key_id) = init_with_config(repo, credentials, key_opts, &config)?;
5858
info!("repository {repo_id} successfully created.");
5959

6060
Ok((key, key_id, config))
@@ -79,13 +79,19 @@ pub(crate) fn init<P, S>(
7979
/// The key used to encrypt the config.
8080
pub(crate) fn init_with_config<P, S>(
8181
repo: &Repository<P, S>,
82-
pass: &str,
82+
credentials: &Credential,
8383
key_opts: &KeyOptions,
8484
config: &ConfigFile,
85-
) -> RusticResult<(Key, KeyId)> {
85+
) -> RusticResult<(Key, Option<KeyId>)> {
8686
repo.be.create()?;
87-
let (key, id) = init_key(repo, key_opts, pass)?;
88-
info!("key {id} successfully added.");
87+
let (key, id) = match credentials {
88+
Credential::Password(password) => {
89+
let (key, id) = init_key(repo, key_opts, password)?;
90+
info!("key {id} successfully added.");
91+
(key, Some(id))
92+
}
93+
Credential::Masterkey(key) => (key.key(), None),
94+
};
8995
save_config(repo, config.clone(), key)?;
9096

9197
Ok((key, id))

crates/core/src/error.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ pub enum ErrorKind {
132132
/// general operations
133133
#[default]
134134
Other,
135-
/// password handling
136-
Password,
135+
/// credentials handling
136+
Credentials,
137137
/// the repository
138138
Repository,
139139
/// unsupported operations

crates/core/src/lib.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ implement [`serde::Serialize`] and [`serde::Deserialize`].
2525
2626
```rust
2727
use rustic_backend::BackendOptions;
28-
use rustic_core::{BackupOptions, ConfigOptions, KeyOptions, PathList,
29-
Repository, RepositoryOptions, SnapshotOptions
28+
use rustic_core::{BackupOptions, ConfigOptions, Credential, KeyOptions,
29+
PathList, Repository, RepositoryOptions, SnapshotOptions
3030
};
3131
3232
// Initialize the repository in a temporary dir
3333
let repo_dir = tempfile::tempdir().unwrap();
3434
35-
let repo_opts = RepositoryOptions::default()
36-
.password("test");
35+
let repo_opts = RepositoryOptions::default();
36+
let credential = Credential::new_masterkey(); // In real life, make sure to save this credential!
3737
3838
// Initialize Backends
3939
let backends = BackendOptions::default()
@@ -45,10 +45,13 @@ implement [`serde::Serialize`] and [`serde::Deserialize`].
4545
4646
let config_opts = ConfigOptions::default();
4747
48-
let _repo = Repository::new(&repo_opts, &backends.clone()).unwrap().init(&key_opts, &config_opts).unwrap();
48+
let _repo = Repository::new(&repo_opts, &backends)
49+
.unwrap()
50+
.init(&credential, &key_opts, &config_opts)
51+
.unwrap();
4952
5053
// We could have used _repo directly, but open the repository again to show how to open it...
51-
let repo = Repository::new(&repo_opts, &backends).unwrap().open().unwrap();
54+
let repo = Repository::new(&repo_opts, &backends).unwrap().open(&credential).unwrap();
5255
5356
// Get all snapshots from the repository
5457
let snaps = repo.get_all_snapshots().unwrap();
@@ -165,5 +168,6 @@ pub use crate::{
165168
FullIndex, IdIndex, IndexedFull, IndexedIds, IndexedStatus, IndexedTree, Open, OpenStatus,
166169
Repository, RepositoryOptions,
167170
command_input::{CommandInput, CommandInputErrorKind},
171+
credentials::{Credential, CredentialOptions},
168172
},
169173
};

crates/core/src/repofile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ pub use {
160160
},
161161
configfile::{Chunker, ConfigFile},
162162
indexfile::{IndexBlob, IndexFile, IndexId, IndexPack},
163-
keyfile::{KeyFile, KeyId},
163+
keyfile::{KeyFile, KeyId, MasterKey},
164164
packfile::{HeaderEntry, PackHeader, PackHeaderLength, PackHeaderRef, PackId},
165165
snapshotfile::{
166166
DeleteOption, PathList, SnapshotFile, SnapshotId, SnapshotModification, SnapshotSummary,

crates/core/src/repofile/keyfile.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -306,28 +306,28 @@ fn log_2(x: u32) -> KeyFileResult<u8> {
306306
///
307307
/// This is used to verify the integrity of the key
308308
#[serde_as]
309-
#[derive(Serialize, Deserialize, Debug)]
310-
pub(crate) struct Mac {
309+
#[derive(Serialize, Deserialize, Debug, Clone)]
310+
pub struct Mac {
311311
/// The key used for the mac
312312
#[serde_as(as = "Base64")]
313-
k: Vec<u8>,
313+
pub k: Vec<u8>,
314314

315315
/// The random value used for the mac
316316
#[serde_as(as = "Base64")]
317-
r: Vec<u8>,
317+
pub r: Vec<u8>,
318318
}
319319

320320
/// The master key of a [`Key`]
321321
///
322322
/// This is used to encrypt the key
323323
#[serde_as]
324-
#[derive(Serialize, Deserialize, Debug)]
325-
pub(crate) struct MasterKey {
324+
#[derive(Serialize, Deserialize, Debug, Clone)]
325+
pub struct MasterKey {
326326
/// The mac of the key
327-
mac: Mac,
327+
pub mac: Mac,
328328
/// The encrypted key
329329
#[serde_as(as = "Base64")]
330-
encrypt: Vec<u8>,
330+
pub encrypt: Vec<u8>,
331331
}
332332

333333
impl MasterKey {
@@ -340,7 +340,7 @@ impl MasterKey {
340340
/// # Returns
341341
///
342342
/// The created [`MasterKey`]
343-
fn from_key(key: Key) -> Self {
343+
pub(crate) fn from_key(key: Key) -> Self {
344344
let (encrypt, k, r) = key.to_keys();
345345
Self {
346346
encrypt,
@@ -349,7 +349,7 @@ impl MasterKey {
349349
}
350350

351351
/// Get the [`Key`] from the [`MasterKey`]
352-
fn key(&self) -> Key {
352+
pub(crate) fn key(&self) -> Key {
353353
Key::from_keys(&self.encrypt, &self.mac.k, &self.mac.r)
354354
}
355355
}
@@ -407,7 +407,7 @@ pub(crate) fn find_key_in_backend<B: ReadBackend>(
407407
}
408408

409409
Err(RusticError::new(
410-
ErrorKind::Password,
410+
ErrorKind::Credentials,
411411
"The password that has been entered, seems to be incorrect. No suitable key found for the given password. Please check your password and try again.",
412412
).attach_error_code("C002"))
413413
}

0 commit comments

Comments
 (0)