Browse Source

Redo some docs, remove some superflous ones.

Thomas Kerber 1 year ago
parent
commit
560d2f61d5

+ 5
- 0
README.md View File

@@ -12,3 +12,8 @@ goblin's is designed to manage passwords in a version controlled container,
12 12
 allowing reverting to previous values and merging keyrings on different
13 13
 devices. It is primarily controlled through a [jsonrpc](http://www.jsonrpc.org)
14 14
 API, allowing users to easily extend the core functionality.
15
+
16
+## Documentation
17
+
18
+* [`goblin-core`](https://doc.drwx.org/goblin/goblin_core/)
19
+

+ 21
- 7
goblin-core/src/crypto.rs View File

@@ -10,22 +10,22 @@ use zero::ZeroBox;
10 10
 /// A credential which can be used to unlock a vault.
11 11
 #[derive(Clone, Copy)]
12 12
 pub enum Credential<'a> {
13
-    /// A symmetric encryption key, used directly.
13
+    #[allow(missing_docs)]
14 14
     #[doc(hidden)]
15 15
     Key(&'a Key),
16
-    /// A passphrase used to generate and retrieve the symmetric encryption key.
16
+    #[allow(missing_docs)]
17 17
     Passphrase(&'a [u8]),
18 18
 }
19 19
 
20
-#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
21 20
 /// A sha3-256 hash.
21
+#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
22 22
 pub struct Hash(
23 23
     #[serde(serialize_with = "as_hex", deserialize_with = "from_hex32")]
24 24
     [u8; 32]
25 25
 );
26 26
 
27 27
 impl Hash {
28
-    /// Create a hash of the given data.
28
+    #[allow(missing_docs)]
29 29
     pub fn new(data: &[u8]) -> Self {
30 30
         let mut ret = [0u8; 32];
31 31
         digest::hash(digest::Algorithm::Sha3_256, data, &mut ret[..]);
@@ -45,7 +45,7 @@ impl AsRef<[u8]> for Hash {
45 45
     }
46 46
 }
47 47
 
48
-/// Describes a 128-bit salt, used for secure key generation.
48
+/// A 128-bit salt, used for secure key derivation.
49 49
 #[derive(Serialize, Deserialize)]
50 50
 pub struct Salt(
51 51
     #[serde(serialize_with = "as_hex", deserialize_with = "from_hex16")]
@@ -53,7 +53,7 @@ pub struct Salt(
53 53
 );
54 54
 
55 55
 impl Salt {
56
-    /// Creates a new salt from a secure random pool.
56
+    #[allow(missing_docs)]
57 57
     pub fn new() -> Self {
58 58
         let mut salt = [0u8; 16];
59 59
         randomize(&mut salt[..]);
@@ -72,7 +72,7 @@ impl AsRef<[u8]> for Salt {
72 72
 pub struct Key(ZeroBox<[u8; 32]>);
73 73
 
74 74
 impl Key {
75
-    /// Generates a new, random key.
75
+    #[allow(missing_docs)]
76 76
     pub fn new() -> Self {
77 77
         let mut key = [0u8; 32];
78 78
         randomize(&mut key[..]);
@@ -127,6 +127,9 @@ impl AsRef<[u8]> for Key {
127 127
     }
128 128
 }
129 129
 
130
+/// Encrypts and writes out some data using AES-CTR-256.
131
+///
132
+/// A new 256-bit salt is prepended to the data before writing it out.
130 133
 pub fn encrypt<W: Write>(mut data: Vec<u8>, key: &Key, mut out: W) -> Result<()> {
131 134
     let mut ctr = [0u8; 16];
132 135
     randomize(&mut ctr[..]);
@@ -139,6 +142,7 @@ pub fn encrypt<W: Write>(mut data: Vec<u8>, key: &Key, mut out: W) -> Result<()>
139 142
     Ok(())
140 143
 }
141 144
 
145
+/// Reads and decrypts data, as inverse of `encrypt`.
142 146
 pub fn decrypt<R: Read>(key: &Key, mut input: R) -> Result<ZeroBox<Vec<u8>>> {
143 147
     let mut ctr = [0u8; 16];
144 148
     let mut data = Vec::new();
@@ -151,6 +155,7 @@ pub fn decrypt<R: Read>(key: &Key, mut input: R) -> Result<ZeroBox<Vec<u8>>> {
151 155
     Ok(ZeroBox::new(data))
152 156
 }
153 157
 
158
+/// Generates cryptographically secure randomness in a buffer.
154 159
 fn randomize(buf: &mut [u8]) {
155 160
     rand::randomize(rand::Level::Strong, buf);
156 161
 }
@@ -165,4 +170,13 @@ mod tests {
165 170
         let keyfile = [0u8; 64];
166 171
         assert!(Key::from_keyfile(&keyfile[..], &Key::new()).is_err());
167 172
     }
173
+
174
+    #[test]
175
+    fn test_decrypt() {
176
+        let key = Key::new();
177
+        let data = "foobar".as_bytes().to_owned();
178
+        let mut enc = Vec::new();
179
+        encrypt(data, &key, &mut enc).unwrap();
180
+        assert_eq!(AsRef::<[u8]>::as_ref(&decrypt(&key, &enc[..]).unwrap()), "foobar".as_bytes());
181
+    }
168 182
 }

+ 3
- 2
goblin-core/src/err.rs View File

@@ -14,12 +14,12 @@ use std::sync::PoisonError;
14 14
 #[cfg(all(feature = "basedirs", unix))]
15 15
 use xdg::BaseDirectoriesError;
16 16
 
17
-/// The result of an operation which may fail within goblin core.
17
+#[allow(missing_docs)]
18 18
 pub type Result<T> = result::Result<T, Error>;
19 19
 
20 20
 use Error::*;
21 21
 
22
-/// An error from within goblin core.
22
+#[allow(missing_docs)]
23 23
 #[derive(Debug)]
24 24
 pub enum Error {
25 25
     /// An error from the gcrypt library.
@@ -73,6 +73,7 @@ pub enum Error {
73 73
     InvalidUrl(String),
74 74
     /// The hash of an improperly initialized commit was accessed.
75 75
     ImproperCommit,
76
+    /// Can't actually occur, to stop API breakage on adding errors.
76 77
     #[doc(hidden)]
77 78
     Nonexhaustive,
78 79
 }

+ 28
- 32
goblin-core/src/format.rs View File

@@ -32,6 +32,9 @@ pub struct Vault {
32 32
 }
33 33
 
34 34
 impl Vault {
35
+    /// Loads a vault, but does not yet unlock it.
36
+    ///
37
+    /// Must be followed by an unlock.
35 38
     fn load(location: VaultLocation) -> Result<Self> {
36 39
         let memtar = MemTar::open(Cursor::new(location.open()?))?;
37 40
         let md: MetaData = serde_json::from_slice(memtar.entry("metadata.json")?)?;
@@ -49,14 +52,14 @@ impl Vault {
49 52
         })
50 53
     }
51 54
 
52
-    /// Opens an existing vault at the given location with the given credentials.
55
+    #[allow(missing_docs)]
53 56
     pub fn open(location: VaultLocation, cred: Credential) -> Result<Self> {
54 57
         let mut vault = Vault::load(location)?;
55 58
         vault.unlock(cred)?;
56 59
         Ok(vault)
57 60
     }
58 61
 
59
-    /// Retrieves a list of all commit hashes contained within the vault.
62
+    #[allow(missing_docs)]
60 63
     pub fn commits(&self) -> Vec<Hash> {
61 64
         self.memtar
62 65
             .keys()
@@ -90,7 +93,7 @@ impl Vault {
90 93
             .collect()
91 94
     }
92 95
 
93
-    /// Retrieves the head commit, or `None` if there is none.
96
+    #[allow(missing_docs)]
94 97
     pub fn head_commit(&self) -> Result<Option<Commit>> {
95 98
         Ok(match self.metadata.head {
96 99
             Some(h) => Some(Commit::from_hash(&self, h)?),
@@ -98,7 +101,7 @@ impl Vault {
98 101
         })
99 102
     }
100 103
 
101
-    /// Retrieves the hash of the head commit, or `None` if there is none.
104
+    #[allow(missing_docs)]
102 105
     pub fn head(&self) -> Option<Hash> {
103 106
         self.metadata.head
104 107
     }
@@ -133,7 +136,7 @@ impl Vault {
133 136
         Ok(())
134 137
     }
135 138
 
136
-    /// Returns the location the vault is saved at.
139
+    #[allow(missing_docs)]
137 140
     pub fn location(&self) -> &VaultLocation {
138 141
         &self.location
139 142
     }
@@ -145,7 +148,7 @@ impl From<VaultMut> for Vault {
145 148
     }
146 149
 }
147 150
 
148
-/// A mutable `Vault`.
151
+#[allow(missing_docs)]
149 152
 pub struct VaultMut {
150 153
     modified: bool,
151 154
     // May ONLY be None if the item was removed during deconstruction. This drops drop from doing
@@ -157,7 +160,7 @@ impl VaultMut {
157 160
     /// Merges a second vault into this one.
158 161
     ///
159 162
     /// This operation imports new files from the second vault, and returns a vector of head
160
-    /// commits (usually, and at most, two).
163
+    /// commits (usually, and at most, two). It does not start the creation of a merge commit.
161 164
     pub fn merge(&mut self, sec: VaultLocation) -> Result<Vec<Hash>> {
162 165
         info!("merging vault '{}' into '{}'", sec, self.location);
163 166
         let v = Vault::open(sec, Credential::Key(self.key.as_ref().unwrap()))?;
@@ -171,9 +174,7 @@ impl VaultMut {
171 174
         )
172 175
     }
173 176
 
174
-    /// Creates a new vault at the given file with the given passphrase.
175
-    ///
176
-    /// Note that the vault file is not actually created until the vault is closed.
177
+    #[allow(missing_docs)]
177 178
     pub fn create(location: VaultLocation, passphrase: &[u8]) -> Result<Self> {
178 179
         info!("creating new vault '{}'", location);
179 180
         let mut vault = VaultMut {
@@ -196,7 +197,7 @@ impl VaultMut {
196 197
         Ok(vault)
197 198
     }
198 199
 
199
-    /// Resets the vault to the given commit hash, if it exists.
200
+    #[allow(missing_docs)]
200 201
     pub fn reset(&mut self, commit: Hash) -> Result<()> {
201 202
         // Ensure the commit exists
202 203
         Commit::from_hash(self, commit)?;
@@ -230,9 +231,6 @@ impl VaultMut {
230 231
         Ok(())
231 232
     }
232 233
 
233
-    /// Closes the vault, writing any changes to the vault file.
234
-    ///
235
-    /// This is also called when the vault is dropped, although errors are ignored.
236 234
     pub fn close(mut self) -> Result<()> {
237 235
         self.flush()
238 236
     }
@@ -252,7 +250,7 @@ impl VaultMut {
252 250
         Ok(())
253 251
     }
254 252
 
255
-    /// Adds a new passphrase.
253
+    #[allow(missing_docs)]
256 254
     pub fn add_passphrase(&mut self, passphrase: &[u8]) -> Result<()> {
257 255
         let derived_key = Key::derive(passphrase, &self.metadata.salt)?;
258 256
         let path = format!("{}.key", Hash::new(derived_key.as_ref()));
@@ -288,7 +286,7 @@ impl VaultMut {
288 286
         Ok(())
289 287
     }
290 288
 
291
-    /// Returns the immutable vault contained within.
289
+    #[allow(missing_docs)]
292 290
     pub fn into_inner(mut self) -> Vault {
293 291
         // duplicate drop, as drop will not function after this.
294 292
         self.flush().ok();
@@ -331,13 +329,13 @@ impl Drop for VaultMut {
331 329
     }
332 330
 }
333 331
 
334
-/// Defines a change to the keyring.
332
+/// Defines an atomic change to the keyring.
335 333
 #[derive(Serialize, Deserialize, Clone)]
336 334
 #[serde(tag = "op", content = "arg", rename_all = "snake_case")]
337 335
 pub enum Delta {
338
-    /// Inserts a new value at the given path.
336
+    #[allow(missing_docs)]
339 337
     Insert(Path, Value),
340
-    /// Removes the value at the given path.
338
+    #[allow(missing_docs)]
341 339
     Rm(Path),
342 340
     /// Moves a value from the first path to the second.
343 341
     Mv(Path, Path),
@@ -402,23 +400,20 @@ impl Delta {
402 400
 #[derive(Serialize, Deserialize, Clone)]
403 401
 pub struct Commit {
404 402
     /// The previous commit hashes.
405
-    ///
406
-    /// If empty, the commit is an initial commit.
407
-    ///
408
-    /// If contains multiple previous commits, the commit is a merge commit.
409 403
     pub previous: Vec<Hash>,
410 404
     /// The commit's creation time.
411 405
     #[serde(serialize_with = "ser_time", deserialize_with = "de_time")]
412 406
     pub ctime: SystemTime,
413
-    /// The deltas composing the commit.
407
+    /// The deltas composing the commit, in the order they are applied.
414 408
     pub deltas: Vec<Delta>,
415
-    /// The commit hash
409
+    /// The commit hash.
416 410
     #[serde(skip)]
417 411
     pub hash: Option<Hash>,
418 412
 }
419 413
 
420 414
 impl Commit {
421
-    /// Creates a new commit in the given vault for a set of deltas.
415
+    /// Creates a new commit with the head as its predecessor.
416
+    #[allow(missing_docs)]
422 417
     pub fn new(vault: &mut VaultMut, deltas: Vec<Delta>) -> StdResult<Self, (Vec<Delta>, Error)> {
423 418
         let pred = if let Some(hash) = vault.metadata.head {
424 419
             vec![hash]
@@ -428,7 +423,7 @@ impl Commit {
428 423
         Commit::new_full(vault, deltas, pred).map_err(|(d, _, e)| (d, e))
429 424
     }
430 425
 
431
-    /// Creates a new commit in the given vault for a set of deltas and predecessor hashes.
426
+    #[allow(missing_docs)]
432 427
     pub fn new_full(
433 428
         vault: &mut VaultMut,
434 429
         deltas: Vec<Delta>,
@@ -473,7 +468,7 @@ impl Commit {
473 468
         Ok(())
474 469
     }
475 470
 
476
-    /// Retrieves a commit from the given hash.
471
+    #[allow(missing_docs)]
477 472
     pub fn from_hash(vault: &Vault, hash: Hash) -> Result<Self> {
478 473
         let path = format!("{}.commit", hash);
479 474
         let mut f = &vault.memtar.entry(&path)?[..];
@@ -491,7 +486,7 @@ impl Commit {
491 486
         Ok(ret)
492 487
     }
493 488
 
494
-    /// Retrieves the previous commits.
489
+    #[allow(missing_docs)]
495 490
     pub fn previous(&self, vault: &Vault) -> Result<Vec<Self>> {
496 491
         let mut ret = Vec::with_capacity(self.previous.len());
497 492
         for h in &self.previous {
@@ -511,10 +506,11 @@ impl Commit {
511 506
 
512 507
     /// Retrieves the immediate dominator of a set of commits.
513 508
     ///
514
-    /// This is playing somewhat loose with the definition of immediate dominator;
515
-    /// here it is taken to mean the node that strictly dominates each commit in the set, but does
516
-    /// not strictly dominate any other node that strictly dominates each commit in the set.
509
+    /// This is playing somewhat loose with the definition of immediate dominator; here it is taken
510
+    /// to mean the node that strictly dominates each commit in the set, but does not strictly
511
+    /// dominate any other node that strictly dominates each commit in the set.
517 512
     pub fn idom_mult(commits: Vec<Commit>, vault: &Vault) -> Result<Option<Self>> {
513
+        // TODO: rewrite, this is a mess. Possibly create a graph module just for this?
518 514
         if commits.len() == 0 {
519 515
             return Ok(None);
520 516
         }

+ 1
- 2
goblin-core/src/ipc/rpc_def.rs View File

@@ -4,11 +4,10 @@ use format::{Commit, Delta};
4 4
 use jsonrpc_core::types::error::{Error, ErrorCode};
5 5
 use keyring::{self, Path, Value};
6 6
 use location::VaultLocation;
7
-use perm::{Access, PermissionModel, UnlockSpec};
7
+use perm::{Access, AccessControl, UnlockSpec};
8 8
 use serde_json;
9 9
 use state::VaultState;
10 10
 use std::error::Error as StdError;
11
-use std::str::FromStr;
12 11
 use std::sync::{Arc, PoisonError, RwLock};
13 12
 use zero::ZeroBox;
14 13
 

+ 10
- 11
goblin-core/src/keyring.rs View File

@@ -4,7 +4,7 @@ use format::{Commit, Delta, Vault};
4 4
 use std::collections::HashMap;
5 5
 use zero::ZeroBox;
6 6
 
7
-/// Used to identify elements of the keyring.
7
+/// A UNIX path-like identifier of values in a keyring.
8 8
 pub type Path = ZeroBox<String>;
9 9
 
10 10
 impl Path {
@@ -48,7 +48,7 @@ impl<'a> From<&'a str> for Path {
48 48
 /// Used to identify elements of the keyring.
49 49
 pub type Value = ZeroBox<String>;
50 50
 
51
-/// Describes the value of a keyring entry.
51
+/// An entry in a keyring.
52 52
 #[derive(Clone, PartialEq, Eq, Debug)]
53 53
 pub enum Entry {
54 54
     /// A raw data value, e.g. a password.
@@ -58,7 +58,7 @@ pub enum Entry {
58 58
 }
59 59
 
60 60
 impl Entry {
61
-    /// Constructs a value entry from a string.
61
+    /// Convinience constructor for value entries.
62 62
     pub fn value(val: &str) -> Self {
63 63
         Entry::Value(ZeroBox::new(val.to_owned()))
64 64
     }
@@ -69,12 +69,11 @@ impl Entry {
69 69
 pub struct Keyring(HashMap<Path, Entry>);
70 70
 
71 71
 impl Keyring {
72
-    /// Creates a new, empty keyring.
73 72
     pub fn empty() -> Self {
74 73
         Keyring(HashMap::new())
75 74
     }
76 75
 
77
-    /// Constructs a keyring from a given vault.
76
+    #[allow(missing_docs)]
78 77
     pub fn from_vault(vault: &Vault) -> Result<Self> {
79 78
         info!("constructing keyring");
80 79
         if let Some(i) = vault.head_commit()? {
@@ -84,12 +83,12 @@ impl Keyring {
84 83
         }
85 84
     }
86 85
 
87
-    /// Constructs a keyring from a given commit hash.
86
+    #[allow(missing_docs)]
88 87
     pub fn from_hash(vault: &Vault, hash: Hash) -> Result<Self> {
89 88
         Self::from_commit(vault, Commit::from_hash(vault, hash)?)
90 89
     }
91 90
 
92
-    /// Constructs a keyring from a given commit.
91
+    #[allow(missing_docs)]
93 92
     pub fn from_commit(vault: &Vault, mut commit: Commit) -> Result<Self> {
94 93
         debug!("constructing keyring from commit {}", commit.hash()?);
95 94
         let mut hist_chain = vec![];
@@ -176,7 +175,7 @@ impl Keyring {
176 175
         );
177 176
     }
178 177
 
179
-    /// Replays a commit on the keyring.
178
+    #[allow(missing_docs)]
180 179
     pub fn replay(&mut self, commit: Commit) {
181 180
         if let Ok(h) = commit.hash() {
182 181
             debug!("replaying commit {}", h);
@@ -186,7 +185,7 @@ impl Keyring {
186 185
         }
187 186
     }
188 187
 
189
-    /// Applies a delta to the keyring.
188
+    #[allow(missing_docs)]
190 189
     pub fn apply(&mut self, delta: &Delta) {
191 190
         match delta {
192 191
             &Delta::Insert(ref k, ref v) => {
@@ -232,7 +231,7 @@ impl Keyring {
232 231
         }
233 232
     }
234 233
 
235
-    /// Gets a raw value from the keyring.
234
+    #[allow(missing_docs)]
236 235
     pub fn get_raw<T: AsRef<str>>(&self, path: T) -> Option<&Entry> {
237 236
         self.0.get(path.as_ref())
238 237
     }
@@ -250,7 +249,7 @@ impl Keyring {
250 249
         }
251 250
     }
252 251
 
253
-    /// Returns a list of all paths in the keyring.
252
+    #[allow(missing_docs)]
254 253
     pub fn keys(&self) -> Vec<&Path> {
255 254
         self.0.keys().collect()
256 255
     }

+ 2
- 3
goblin-core/src/location.rs View File

@@ -17,12 +17,11 @@ use std::str::FromStr;
17 17
 #[cfg(all(feature = "basedirs", unix))]
18 18
 use xdg::BaseDirectories;
19 19
 
20
-/// Describes where a vault is stored
20
+#[allow(missing_docs)]
21 21
 #[derive(Debug, Clone)]
22 22
 pub enum VaultLocation {
23
-    /// In a file on the local system.
23
+    #[allow(missing_docs)]
24 24
     File(PathBuf),
25
-    /// In a file over ssh.
26 25
     #[cfg(feature = "ssh")]
27 26
     #[doc(hidden)]
28 27
     Ssh(ssh::FileRef),

+ 7
- 0
goblin-core/src/memtar.rs View File

@@ -4,6 +4,7 @@ use std::ops::Deref;
4 4
 use std::path::{Path, PathBuf};
5 5
 use tar;
6 6
 
7
+/// A tar archive in memory.
7 8
 #[derive(Clone)]
8 9
 pub struct MemTar {
9 10
     memmap: HashMap<PathBuf, MemEntry>,
@@ -14,6 +15,7 @@ impl MemTar {
14 15
         MemTar { memmap: HashMap::new() }
15 16
     }
16 17
 
18
+    /// Reads a tar archive into memory.
17 19
     pub fn open<R: Read>(r: R) -> io::Result<Self> {
18 20
         let mut map = HashMap::new();
19 21
         for entry in tar::Archive::new(r).entries()? {
@@ -24,6 +26,7 @@ impl MemTar {
24 26
         Ok(MemTar { memmap: map })
25 27
     }
26 28
 
29
+    /// Writes the tar archive out.
27 30
     pub fn export<W: Write>(&self, w: W) -> io::Result<()> {
28 31
         let mut builder = tar::Builder::new(w);
29 32
         for (_, entry) in self.memmap.iter() {
@@ -33,6 +36,7 @@ impl MemTar {
33 36
         Ok(())
34 37
     }
35 38
 
39
+    /// Gets a path within the tar file.
36 40
     pub fn entry<P: AsRef<Path>>(&self, path: P) -> io::Result<&MemEntry> {
37 41
         if let Some(entry) = self.memmap.get(path.as_ref()) {
38 42
             Ok(entry)
@@ -44,6 +48,7 @@ impl MemTar {
44 48
         }
45 49
     }
46 50
 
51
+    #[allow(missing_docs)]
47 52
     pub fn create<P: AsRef<Path>>(&mut self, path: P, data: Vec<u8>) -> io::Result<()> {
48 53
         self.memmap.insert(
49 54
             path.as_ref().to_owned(),
@@ -52,6 +57,7 @@ impl MemTar {
52 57
         Ok(())
53 58
     }
54 59
 
60
+    #[allow(missing_docs)]
55 61
     pub fn rm<P: AsRef<Path>>(&mut self, path: P) -> io::Result<()> {
56 62
         if self.memmap.remove(path.as_ref()).is_some() {
57 63
             Ok(())
@@ -82,6 +88,7 @@ impl Deref for MemTar {
82 88
     }
83 89
 }
84 90
 
91
+/// A file in a memory tar.
85 92
 #[derive(Clone)]
86 93
 pub struct MemEntry {
87 94
     header: tar::Header,

+ 15
- 4
goblin-core/src/perm.rs View File

@@ -7,7 +7,8 @@ use std::time::{Duration, Instant};
7 7
 
8 8
 const DEFAULT_TIMEOUT_SECS: u64 = 120;
9 9
 
10
-pub trait PermissionModel {
10
+#[allow(missing_docs)]
11
+pub trait AccessControl {
11 12
     fn allowed(&self, access: &Access) -> bool;
12 13
 
13 14
     fn request(&self, access: &Access) -> Result<()> {
@@ -19,43 +20,53 @@ pub trait PermissionModel {
19 20
     }
20 21
 }
21 22
 
23
+/// A set of unlock operations defining the permissions to a keyring state.
24
+#[allow(missing_docs)]
22 25
 pub struct Permissions(Vec<Unlock>);
23 26
 
24 27
 impl Permissions {
28
+    #[allow(missing_docs)]
25 29
     pub fn new() -> Self {
26 30
         Permissions(Vec::new())
27 31
     }
28 32
 
33
+    /// Removes dead unlocks from the permission set.
29 34
     pub fn purge(&mut self) -> bool {
30 35
         let t = Instant::now();
31 36
         self.0.retain(|u| !u.expired(t));
32 37
         self.0.len() == 0
33 38
     }
34 39
 
40
+    /// Whether any of the permissions may require write access.
35 41
     pub fn requires_write(&self) -> bool {
36 42
         self.0.iter().any(|u| u.write)
37 43
     }
38 44
 
45
+    /// Whether any of the permissions may require read access.
39 46
     pub fn requires_read(&self) -> bool {
40 47
         self.0.len() > 0
41 48
     }
42 49
 
50
+    /// Revokes a precise access. Only unlocks matching in scope and type (read or write) exactly
51
+    /// are revoked.
43 52
     pub fn lock(&mut self, access: Access) {
44 53
         self.0.retain(|u| {
45 54
             &u.scope != &access.scope || &u.write != &access.write
46 55
         })
47 56
     }
48 57
 
58
+    /// Adds an unlock.
49 59
     pub fn unlock(&mut self, spec: UnlockSpec) {
50 60
         self.0.push(spec.into())
51 61
     }
52 62
 
63
+    /// Revokes any permissions that may require write access.
53 64
     pub fn coerce_read(&mut self) {
54 65
         self.0.retain(|u| !u.write);
55 66
     }
56 67
 }
57 68
 
58
-impl PermissionModel for Permissions {
69
+impl AccessControl for Permissions {
59 70
     fn allowed(&self, access: &Access) -> bool {
60 71
         let t = Instant::now();
61 72
         for perm in &self.0 {
@@ -162,7 +173,7 @@ impl Unlock {
162 173
     }
163 174
 }
164 175
 
165
-impl PermissionModel for Unlock {
176
+impl AccessControl for Unlock {
166 177
     fn allowed(&self, access: &Access) -> bool {
167 178
         (self.write || !access.write) && self.scope.allowed(access)
168 179
     }
@@ -180,7 +191,7 @@ pub enum Scope<'a> {
180 191
     Global,
181 192
 }
182 193
 
183
-impl<'a> PermissionModel for Scope<'a> {
194
+impl<'a> AccessControl for Scope<'a> {
184 195
     fn allowed(&self, access: &Access) -> bool {
185 196
         match (self, &access.scope) {
186 197
             (&Scope::Global, _) => true,

+ 9
- 1
goblin-core/src/ser.rs View File

@@ -2,6 +2,7 @@ use hex::{FromHex, ToHex};
2 2
 use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
3 3
 use std::time::{Duration, SystemTime, UNIX_EPOCH};
4 4
 
5
+/// Serializes the system time as seconds since the unix epoch.
5 6
 pub fn ser_time<S>(t: &SystemTime, ser: S) -> Result<S::Ok, S::Error>
6 7
 where
7 8
     S: Serializer,
@@ -13,6 +14,7 @@ where
13 14
     ser.serialize_i64(secs)
14 15
 }
15 16
 
17
+/// Derializes the system time from seconds since the unix epoch.
16 18
 pub fn de_time<'a, D>(des: D) -> Result<SystemTime, D::Error>
17 19
 where
18 20
     D: Deserializer<'a>,
@@ -24,6 +26,7 @@ where
24 26
     })
25 27
 }
26 28
 
29
+/// Serializes an optional duration to seconds.
27 30
 pub fn ser_opt_dur<S>(d: &Option<Duration>, ser: S) -> Result<S::Ok, S::Error>
28 31
 where
29 32
     S: Serializer,
@@ -31,6 +34,7 @@ where
31 34
     d.map(|d| d.as_secs()).serialize(ser)
32 35
 }
33 36
 
37
+/// Deserializes an optional duration from seconds.
34 38
 pub fn de_opt_dur<'a, D>(des: D) -> Result<Option<Duration>, D::Error>
35 39
 where
36 40
     D: Deserializer<'a>,
@@ -38,7 +42,7 @@ where
38 42
     Option::<u64>::deserialize(des).map(|s| s.map(|s| Duration::from_secs(s)))
39 43
 }
40 44
 
41
-
45
+/// Serializes a binary buffer as a hex string.
42 46
 pub fn as_hex<T, S>(buf: &T, ser: S) -> Result<S::Ok, S::Error>
43 47
 where
44 48
     T: AsRef<[u8]>,
@@ -47,6 +51,7 @@ where
47 51
     ser.serialize_str(&buf.as_ref().to_hex())
48 52
 }
49 53
 
54
+/// Deserializes a binary buffer from a hex string.
50 55
 pub fn from_hex<'a, D>(des: D) -> Result<Vec<u8>, D::Error>
51 56
 where
52 57
     D: Deserializer<'a>,
@@ -56,6 +61,7 @@ where
56 61
     })
57 62
 }
58 63
 
64
+/// Deserializes a n-byte binary buffer from a hex string.
59 65
 fn from_hexn<'a, D>(des: D, n: usize) -> Result<Vec<u8>, D::Error>
60 66
 where
61 67
     D: Deserializer<'a>,
@@ -69,6 +75,7 @@ where
69 75
     })
70 76
 }
71 77
 
78
+/// Deserializes a 16-byte binary buffer from a hex string.
72 79
 pub fn from_hex16<'a, D>(des: D) -> Result<[u8; 16], D::Error>
73 80
 where
74 81
     D: Deserializer<'a>,
@@ -78,6 +85,7 @@ where
78 85
     Ok(r)
79 86
 }
80 87
 
88
+/// Deserializes a 32-byte binary buffer from a hex string.
81 89
 pub fn from_hex32<'a, D>(des: D) -> Result<[u8; 32], D::Error>
82 90
 where
83 91
     D: Deserializer<'a>,

+ 2
- 2
goblin-core/src/state.rs View File

@@ -4,7 +4,7 @@ use err::{Error, Result};
4 4
 use format::{Commit, Delta, Vault, VaultMut};
5 5
 use keyring::{Entry, Keyring, Path, Value};
6 6
 use location::VaultLocation;
7
-use perm::{Access, PermissionModel, Permissions, Scope, UnlockSpec};
7
+use perm::{Access, AccessControl, Permissions, Scope, UnlockSpec};
8 8
 use std::borrow::{Borrow, Cow};
9 9
 use std::collections::HashSet;
10 10
 use std::io;
@@ -280,7 +280,7 @@ impl VaultState {
280 280
     }
281 281
 }
282 282
 
283
-impl PermissionModel for VaultState {
283
+impl AccessControl for VaultState {
284 284
     fn allowed(&self, access: &Access) -> bool {
285 285
         self.permissions.allowed(access)
286 286
     }

Loading…
Cancel
Save