summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2023-01-17 15:23:21 +0100
committerqkzk <qu3nt1n@gmail.com>2023-01-17 15:23:21 +0100
commita3ec3869aa37cc12e60a3c2915ff29a304635d5c (patch)
tree16552c8b39b6401640a4b46c7a734fce57a2ca5a /src
parent78a2cbec6b10ad6d5f58e10662e7d4d6de60012f (diff)
menu with encrypted devices
Diffstat (limited to 'src')
-rw-r--r--src/cryptsetup.rs27
-rw-r--r--src/event_dispatch.rs6
-rw-r--r--src/event_exec.rs46
-rw-r--r--src/main.rs4
-rw-r--r--src/term_manager.rs6
-rw-r--r--src/utils.rs11
6 files changed, 88 insertions, 12 deletions
diff --git a/src/cryptsetup.rs b/src/cryptsetup.rs
index 5498910..f6892e3 100644
--- a/src/cryptsetup.rs
+++ b/src/cryptsetup.rs
@@ -3,6 +3,7 @@ use std::process::{Command, Stdio};
use crate::fm_error::{FmError, FmResult};
use crate::impl_selectable_content;
+use crate::utils::current_username;
#[derive(Debug, Clone, Copy)]
pub enum PasswordKind {
@@ -338,6 +339,32 @@ impl DeviceOpener {
.set_cryptsetup(password),
}
}
+
+ pub fn mount_selected(&mut self) -> FmResult<()> {
+ let username = current_username()?;
+ let passwords = self.content[self.index].password_holder.clone();
+ self.content[self.index]
+ .cryptdevice
+ .open_mount(&username, &passwords)?;
+ Ok(())
+ }
+
+ pub fn umount_selected(&mut self) -> FmResult<()> {
+ let username = current_username()?;
+ let passwords = self.content[self.index].password_holder.clone();
+ self.content[self.index]
+ .cryptdevice
+ .umount_close(&username, &passwords)?;
+ Ok(())
+ }
+
+ pub fn can_mount(&self) -> bool {
+ self.content[self.index].password_holder.can_mount()
+ }
+
+ pub fn can_umount(&self) -> bool {
+ self.content[self.index].password_holder.can_umount()
+ }
}
impl_selectable_content!(Device, DeviceOpener);
diff --git a/src/event_dispatch.rs b/src/event_dispatch.rs
index ed48851..5321254 100644
--- a/src/event_dispatch.rs
+++ b/src/event_dispatch.rs
@@ -96,6 +96,12 @@ impl EventDispatcher {
Mode::Navigate(Navigate::Trash) if c == 'x' => {
EventExec::event_trash_remove_file(status)
}
+ Mode::Navigate(Navigate::EncryptedDrive) if c == 'm' => {
+ EventExec::event_mount_encrypted_drive(status)
+ }
+ Mode::Navigate(Navigate::EncryptedDrive) if c == 'u' => {
+ EventExec::event_umount_encrypted_drive(status)
+ }
Mode::Preview | Mode::Navigate(_) => {
status.selected().set_mode(Mode::Normal);
EventExec::event_normal(status.selected())
diff --git a/src/event_exec.rs b/src/event_exec.rs
index e33b801..3de4e12 100644
--- a/src/event_exec.rs
+++ b/src/event_exec.rs
@@ -1127,6 +1127,9 @@ impl EventExec {
Mode::Navigate(Navigate::History) => EventExec::event_history_prev(status.selected()),
Mode::Navigate(Navigate::Trash) => EventExec::event_trash_prev(status),
Mode::Navigate(Navigate::Shortcut) => EventExec::event_shortcut_prev(status.selected()),
+ Mode::Navigate(Navigate::EncryptedDrive) => {
+ EventExec::event_encrypted_drive_prev(status)
+ }
Mode::Tree => EventExec::event_select_prev_sibling(status)?,
Mode::InputCompleted(_) => {
status.selected().completion.prev();
@@ -1145,6 +1148,9 @@ impl EventExec {
Mode::Navigate(Navigate::History) => EventExec::event_history_next(status.selected()),
Mode::Navigate(Navigate::Trash) => EventExec::event_trash_next(status),
Mode::Navigate(Navigate::Shortcut) => EventExec::event_shortcut_next(status.selected()),
+ Mode::Navigate(Navigate::EncryptedDrive) => {
+ EventExec::event_encrypted_drive_next(status)
+ }
Mode::InputCompleted(_) => status.selected().completion.next(),
Mode::Tree => EventExec::event_select_next_sibling(status)?,
_ => (),
@@ -1260,15 +1266,13 @@ impl EventExec {
EventExec::exec_filter(status)?
}
Mode::InputSimple(InputSimple::Password(password_kind)) => {
- EventExec::exec_password_store(status, password_kind)?
+ EventExec::exec_store_password(status, password_kind)?
}
Mode::Navigate(Navigate::Jump) => EventExec::exec_jump(status)?,
Mode::Navigate(Navigate::History) => EventExec::exec_history(status.selected())?,
Mode::Navigate(Navigate::Shortcut) => EventExec::exec_shortcut(status.selected())?,
Mode::Navigate(Navigate::Trash) => EventExec::event_trash_restore_file(status)?,
- Mode::Navigate(Navigate::EncryptedDrive) => {
- EventExec::event_toggle_encrypted_drive(status)?
- }
+ Mode::Navigate(Navigate::EncryptedDrive) => (),
Mode::InputCompleted(InputCompleted::Exec) => EventExec::exec_exec(status.selected())?,
Mode::InputCompleted(InputCompleted::Search) => {
must_refresh = false;
@@ -1552,22 +1556,46 @@ impl EventExec {
status
.selected()
.set_mode(Mode::Navigate(Navigate::EncryptedDrive));
- Ok(())
+ status.encrypted_devices.update()
}
- pub fn event_toggle_encrypted_drive(_status: &mut Status) -> FmResult<()> {
+ pub fn event_mount_encrypted_drive(status: &mut Status) -> FmResult<()> {
+ if !status.encrypted_devices.can_mount() {
+ Self::event_ask_password(status, PasswordKind::SUDO)?;
+ Self::event_ask_password(status, PasswordKind::CRYPTSETUP)?;
+ }
+ status.encrypted_devices.mount_selected()
+ }
+
+ pub fn event_umount_encrypted_drive(status: &mut Status) -> FmResult<()> {
+ if status.encrypted_devices.can_umount() {
+ Self::event_ask_password(status, PasswordKind::SUDO)?;
+ }
+ status.encrypted_devices.umount_selected()
+ }
+
+ pub fn event_ask_password(status: &mut Status, password_kind: PasswordKind) -> FmResult<()> {
+ status
+ .selected()
+ .set_mode(Mode::InputSimple(InputSimple::Password(password_kind)));
Ok(())
}
- pub fn exec_password_store(status: &mut Status, password_kind: PasswordKind) -> FmResult<()> {
+ pub fn exec_store_password(status: &mut Status, password_kind: PasswordKind) -> FmResult<()> {
let password = status.selected_non_mut().input.string();
status
.encrypted_devices
.set_password(password_kind, password);
- status.selected().reset_mode();
- status.clear_flags_and_reset_view()?;
Ok(())
}
+
+ pub fn event_encrypted_drive_next(status: &mut Status) {
+ status.encrypted_devices.next()
+ }
+
+ pub fn event_encrypted_drive_prev(status: &mut Status) {
+ status.encrypted_devices.prev()
+ }
}
fn string_to_path(path_string: &str) -> FmResult<path::PathBuf> {
diff --git a/src/main.rs b/src/main.rs
index 5c719e8..0402092 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -18,7 +18,7 @@ use fm::utils::{drop_everything, init_term, print_on_quit};
/// Init the status and display and listen to events (keyboard, mouse, resize, custom...).
/// The application is redrawn after every event.
/// When the user issues a quit event, the main loop is broken and we reset the cursor.
-fn main2() -> FmResult<()> {
+fn main() -> FmResult<()> {
set_logger()?;
info!("fm is starting");
@@ -49,7 +49,7 @@ fn main2() -> FmResult<()> {
Ok(())
}
-fn main() -> FmResult<()> {
+fn _main() -> FmResult<()> {
use users::{get_current_uid, get_user_by_uid};
use fm::cryptsetup::{filter_crypto_devices_lines, get_devices, CryptoDevice, PasswordHolder};
diff --git a/src/term_manager.rs b/src/term_manager.rs
index 2ebf481..b13617d 100644
--- a/src/term_manager.rs
+++ b/src/term_manager.rs
@@ -522,7 +522,11 @@ impl<'a> WinSecondary<'a> {
canvas.print_with_attr(2, 1, "encrypted devices", Self::ATTR_YELLOW)?;
for (i, device) in status.encrypted_devices.content.iter().enumerate() {
let row = calc_line_row(i, tab) + 2;
- canvas.print(row, 3, &device.cryptdevice.as_string()?)?;
+ let mut attr = Attr::default();
+ if i == status.encrypted_devices.index() {
+ attr.effect |= Effect::REVERSE;
+ }
+ canvas.print_with_attr(row, 3, &device.cryptdevice.as_string()?, attr)?;
}
Ok(())
}
diff --git a/src/utils.rs b/src/utils.rs
index 70c4a94..337a592 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -4,6 +4,7 @@ use std::sync::Arc;
use sysinfo::{Disk, DiskExt};
use tuikit::term::Term;
+use users::{get_current_uid, get_user_by_uid};
use crate::event_dispatch::EventDispatcher;
use crate::fileinfo::human_size;
@@ -94,3 +95,13 @@ pub fn filename_from_path(path: &std::path::Path) -> FmResult<&str> {
.to_str()
.ok_or_else(|| FmError::custom("filename from path", "couldn't parse the filename"))
}
+
+pub fn current_username() -> FmResult<String> {
+ let user = get_user_by_uid(get_current_uid())
+ .ok_or_else(|| FmError::custom("username", "couldn't read username"))?;
+ Ok(user
+ .name()
+ .to_str()
+ .ok_or_else(|| FmError::custom("username", "couldn't read username"))?
+ .to_owned())
+}