mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
bookmarks client OK
This commit is contained in:
@@ -44,7 +44,7 @@ use std::time::SystemTime;
|
|||||||
///
|
///
|
||||||
/// BookmarksClient provides a layer between the host system and the bookmarks module
|
/// BookmarksClient provides a layer between the host system and the bookmarks module
|
||||||
pub struct BookmarksClient {
|
pub struct BookmarksClient {
|
||||||
pub hosts: UserHosts,
|
hosts: UserHosts,
|
||||||
bookmarks_file: PathBuf,
|
bookmarks_file: PathBuf,
|
||||||
key: String,
|
key: String,
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ impl BookmarksClient {
|
|||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let client: BookmarksClient = BookmarksClient {
|
let mut client: BookmarksClient = BookmarksClient {
|
||||||
hosts: default_hosts,
|
hosts: default_hosts,
|
||||||
bookmarks_file: PathBuf::from(bookmarks_file),
|
bookmarks_file: PathBuf::from(bookmarks_file),
|
||||||
key,
|
key,
|
||||||
@@ -79,11 +79,23 @@ impl BookmarksClient {
|
|||||||
if let Err(err) = client.write_bookmarks() {
|
if let Err(err) = client.write_bookmarks() {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Load bookmarks from file
|
||||||
|
if let Err(err) = client.read_bookmarks() {
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Load key
|
// Load key
|
||||||
Ok(client)
|
Ok(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### iter_bookmarks
|
||||||
|
///
|
||||||
|
/// Iterate over bookmarks keys
|
||||||
|
pub fn iter_bookmarks(&self) -> Box<dyn Iterator<Item = &String> + '_> {
|
||||||
|
Box::new(self.hosts.bookmarks.keys())
|
||||||
|
}
|
||||||
|
|
||||||
/// ### get_bookmark
|
/// ### get_bookmark
|
||||||
///
|
///
|
||||||
/// Get bookmark associated to key
|
/// Get bookmark associated to key
|
||||||
@@ -102,7 +114,7 @@ impl BookmarksClient {
|
|||||||
_ => FileTransferProtocol::Sftp,
|
_ => FileTransferProtocol::Sftp,
|
||||||
},
|
},
|
||||||
entry.username.clone(),
|
entry.username.clone(),
|
||||||
match entry.password {
|
match &entry.password {
|
||||||
// Decrypted password if Some; if decryption fails return None
|
// Decrypted password if Some; if decryption fails return None
|
||||||
Some(pwd) => match self.decrypt_str(pwd.as_str()) {
|
Some(pwd) => match self.decrypt_str(pwd.as_str()) {
|
||||||
Ok(decrypted_pwd) => Some(decrypted_pwd),
|
Ok(decrypted_pwd) => Some(decrypted_pwd),
|
||||||
@@ -130,6 +142,19 @@ impl BookmarksClient {
|
|||||||
self.hosts.bookmarks.insert(name, host);
|
self.hosts.bookmarks.insert(name, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### del_bookmark
|
||||||
|
///
|
||||||
|
/// Delete entry from bookmarks
|
||||||
|
pub fn del_bookmark(&mut self, name: &String) {
|
||||||
|
let _ = self.hosts.bookmarks.remove(name);
|
||||||
|
}
|
||||||
|
/// ### iter_recents
|
||||||
|
///
|
||||||
|
/// Iterate over recents keys
|
||||||
|
pub fn iter_recents(&self) -> Box<dyn Iterator<Item = &String> + '_> {
|
||||||
|
Box::new(self.hosts.recents.keys())
|
||||||
|
}
|
||||||
|
|
||||||
/// ### get_recent
|
/// ### get_recent
|
||||||
///
|
///
|
||||||
/// Get recent associated to key
|
/// Get recent associated to key
|
||||||
@@ -189,6 +214,13 @@ impl BookmarksClient {
|
|||||||
self.hosts.recents.insert(name, host);
|
self.hosts.recents.insert(name, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### del_recent
|
||||||
|
///
|
||||||
|
/// Delete entry from recents
|
||||||
|
pub fn del_recent(&mut self, name: &String) {
|
||||||
|
let _ = self.hosts.recents.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
/// ### write_bookmarks
|
/// ### write_bookmarks
|
||||||
///
|
///
|
||||||
/// Write bookmarks to file
|
/// Write bookmarks to file
|
||||||
@@ -211,6 +243,33 @@ impl BookmarksClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### read_bookmarks
|
||||||
|
///
|
||||||
|
/// Read bookmarks from file
|
||||||
|
fn read_bookmarks(&mut self) -> Result<(), SerializerError> {
|
||||||
|
// Open bookmarks file for read
|
||||||
|
match OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.open(self.bookmarks_file.as_path())
|
||||||
|
{
|
||||||
|
Ok(reader) => {
|
||||||
|
// Deserialize
|
||||||
|
let deserializer: BookmarkSerializer = BookmarkSerializer {};
|
||||||
|
match deserializer.deserialize(Box::new(reader)) {
|
||||||
|
Ok(hosts) => {
|
||||||
|
self.hosts = hosts;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(err) => Err(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => Err(SerializerError::new_ex(
|
||||||
|
SerializerErrorKind::IoError,
|
||||||
|
err.to_string(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// ### generate_key
|
/// ### generate_key
|
||||||
///
|
///
|
||||||
/// Generate a new AES key and write it to key file
|
/// Generate a new AES key and write it to key file
|
||||||
@@ -285,8 +344,13 @@ impl BookmarksClient {
|
|||||||
match OpenOptions::new().read(true).open(key_file) {
|
match OpenOptions::new().read(true).open(key_file) {
|
||||||
Ok(mut file) => {
|
Ok(mut file) => {
|
||||||
let mut key: String = String::with_capacity(256);
|
let mut key: String = String::with_capacity(256);
|
||||||
file.read_to_string(&mut key);
|
match file.read_to_string(&mut key) {
|
||||||
Ok(key)
|
Ok(_) => Ok(key),
|
||||||
|
Err(err) => Err(SerializerError::new_ex(
|
||||||
|
SerializerErrorKind::IoError,
|
||||||
|
err.to_string(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => Err(SerializerError::new_ex(
|
Err(err) => Err(SerializerError::new_ex(
|
||||||
SerializerErrorKind::IoError,
|
SerializerErrorKind::IoError,
|
||||||
@@ -317,3 +381,125 @@ impl BookmarksClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_system_bookmarks_new() {
|
||||||
|
let tmp_dir: tempfile::TempDir = create_tmp_dir();
|
||||||
|
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||||
|
// Initialize a new bookmarks client
|
||||||
|
let client: BookmarksClient = BookmarksClient::new(cfg_path.as_path(), key_path.as_path()).unwrap();
|
||||||
|
// Verify client
|
||||||
|
assert_eq!(client.hosts.bookmarks.len(), 0);
|
||||||
|
assert_eq!(client.hosts.recents.len(), 0);
|
||||||
|
assert!(client.key.len() > 0);
|
||||||
|
assert_eq!(client.bookmarks_file, cfg_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_system_bookmarks_new_err() {
|
||||||
|
assert!(BookmarksClient::new(Path::new("/tmp/oifoif/omar"), Path::new("/tmp/efnnu/omar")).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_system_bookmarks_new_from_existing() {
|
||||||
|
let tmp_dir: tempfile::TempDir = create_tmp_dir();
|
||||||
|
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||||
|
// Initialize a new bookmarks client
|
||||||
|
let mut client: BookmarksClient = BookmarksClient::new(cfg_path.as_path(), key_path.as_path()).unwrap();
|
||||||
|
// Add some bookmarks
|
||||||
|
client.add_bookmark(String::from("raspberry"), String::from("192.168.1.31"), 22, FileTransferProtocol::Sftp, String::from("pi"), Some(String::from("mypassword")));
|
||||||
|
client.add_recent(String::from("192.168.1.31"), 22, FileTransferProtocol::Sftp, String::from("pi"));
|
||||||
|
let recent_key: String = String::from(client.iter_recents().next().unwrap());
|
||||||
|
assert!(client.write_bookmarks().is_ok());
|
||||||
|
let key: String = client.key.clone();
|
||||||
|
// Re-initialize a client
|
||||||
|
let client: BookmarksClient = BookmarksClient::new(cfg_path.as_path(), key_path.as_path()).unwrap();
|
||||||
|
// Verify it loaded parameters correctly
|
||||||
|
assert_eq!(client.key, key);
|
||||||
|
let bookmark: (String, u16, FileTransferProtocol, String, Option<String>) = client.get_bookmark(&String::from("raspberry")).unwrap();
|
||||||
|
assert_eq!(bookmark.0, String::from("192.168.1.31"));
|
||||||
|
assert_eq!(bookmark.1, 22);
|
||||||
|
assert_eq!(bookmark.2, FileTransferProtocol::Sftp);
|
||||||
|
assert_eq!(bookmark.3, String::from("pi"));
|
||||||
|
assert_eq!(*bookmark.4.as_ref().unwrap(), String::from("mypassword"));
|
||||||
|
let bookmark: (String, u16, FileTransferProtocol, String) = client.get_recent(&recent_key).unwrap();
|
||||||
|
assert_eq!(bookmark.0, String::from("192.168.1.31"));
|
||||||
|
assert_eq!(bookmark.1, 22);
|
||||||
|
assert_eq!(bookmark.2, FileTransferProtocol::Sftp);
|
||||||
|
assert_eq!(bookmark.3, String::from("pi"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_system_bookmarks_manipulate_bookmarks() {
|
||||||
|
let tmp_dir: tempfile::TempDir = create_tmp_dir();
|
||||||
|
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||||
|
// Initialize a new bookmarks client
|
||||||
|
let mut client: BookmarksClient = BookmarksClient::new(cfg_path.as_path(), key_path.as_path()).unwrap();
|
||||||
|
// Add bookmark
|
||||||
|
client.add_bookmark(String::from("raspberry"), String::from("192.168.1.31"), 22, FileTransferProtocol::Sftp, String::from("pi"), Some(String::from("mypassword")));
|
||||||
|
// Get bookmark
|
||||||
|
let bookmark: (String, u16, FileTransferProtocol, String, Option<String>) = client.get_bookmark(&String::from("raspberry")).unwrap();
|
||||||
|
assert_eq!(bookmark.0, String::from("192.168.1.31"));
|
||||||
|
assert_eq!(bookmark.1, 22);
|
||||||
|
assert_eq!(bookmark.2, FileTransferProtocol::Sftp);
|
||||||
|
assert_eq!(bookmark.3, String::from("pi"));
|
||||||
|
assert_eq!(*bookmark.4.as_ref().unwrap(), String::from("mypassword"));
|
||||||
|
// Write bookmarks
|
||||||
|
assert!(client.write_bookmarks().is_ok());
|
||||||
|
// Delete bookmark
|
||||||
|
client.del_bookmark(&String::from("raspberry"));
|
||||||
|
// Get unexisting bookmark
|
||||||
|
assert!(client.get_bookmark(&String::from("raspberry")).is_none());
|
||||||
|
// Write bookmarks
|
||||||
|
assert!(client.write_bookmarks().is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_system_bookmarks_manipulate_recents() {
|
||||||
|
let tmp_dir: tempfile::TempDir = create_tmp_dir();
|
||||||
|
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||||
|
// Initialize a new bookmarks client
|
||||||
|
let mut client: BookmarksClient = BookmarksClient::new(cfg_path.as_path(), key_path.as_path()).unwrap();
|
||||||
|
// Add bookmark
|
||||||
|
client.add_recent(String::from("192.168.1.31"), 22, FileTransferProtocol::Sftp, String::from("pi"));
|
||||||
|
let key: String = String::from(client.iter_recents().next().unwrap());
|
||||||
|
// Get bookmark
|
||||||
|
let bookmark: (String, u16, FileTransferProtocol, String) = client.get_recent(&key).unwrap();
|
||||||
|
assert_eq!(bookmark.0, String::from("192.168.1.31"));
|
||||||
|
assert_eq!(bookmark.1, 22);
|
||||||
|
assert_eq!(bookmark.2, FileTransferProtocol::Sftp);
|
||||||
|
assert_eq!(bookmark.3, String::from("pi"));
|
||||||
|
// Write bookmarks
|
||||||
|
assert!(client.write_bookmarks().is_ok());
|
||||||
|
// Delete bookmark
|
||||||
|
client.del_recent(&key);
|
||||||
|
// Get unexisting bookmark
|
||||||
|
assert!(client.get_bookmark(&key).is_none());
|
||||||
|
// Write bookmarks
|
||||||
|
assert!(client.write_bookmarks().is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### get_paths
|
||||||
|
///
|
||||||
|
/// Get paths for configuration and key for bookmarks
|
||||||
|
fn get_paths(dir: &Path) -> (PathBuf, PathBuf) {
|
||||||
|
let mut k: PathBuf = PathBuf::from(dir);
|
||||||
|
let mut c: PathBuf = k.clone();
|
||||||
|
k.push("bookmarks.key");
|
||||||
|
c.push("bookmarks.toml");
|
||||||
|
(c, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### create_tmp_dir
|
||||||
|
///
|
||||||
|
/// Create temporary directory
|
||||||
|
fn create_tmp_dir() -> tempfile::TempDir {
|
||||||
|
tempfile::TempDir::new().ok().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user