Skip to content

Commit

Permalink
Implement per-user root directory
Browse files Browse the repository at this point in the history
This builds on github PR #97 to add a configurable optional home
directory per user as requested in issue #85.

The user's home gets specified in a JSON file pointed to by the
`---usr-json-path` argument. The `root` property needs to be set:

```json
[
  {
    "username": "alice",
    "password": "12345678",
    "root": "alice"
  },
  {
    "username": "bob",
    "password": "secret",
    "root": "bob"
  }
]
```

At the moment if the `root` is not specified then the user will gain
access to the root of the storage back-end.
  • Loading branch information
hannesdejager committed Jul 9, 2021
1 parent ff3bea4 commit d7b931b
Show file tree
Hide file tree
Showing 6 changed files with 389 additions and 11 deletions.
39 changes: 38 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ musl = ["rest_auth", "cloud_storage", "jsonfile_auth"]
# Features used in our docker builds
docker = ["musl"]

[dev-dependencies]
pretty_assertions = "0.7.1"

[build-dependencies]
built = "0.3"

Expand Down
14 changes: 11 additions & 3 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use bitflags::bitflags;
use libunftp::auth::{AuthenticationError, Credentials, DefaultUser, UserDetail};
use serde::Deserialize;
use std::fmt::Formatter;
use std::path::PathBuf;

/// The unFTP user details
#[derive(Debug, PartialEq)]
Expand All @@ -16,9 +17,8 @@ pub struct User {
pub vfs_permissions: VfsOperations,
/// For some users we know they will only upload a certain type of file
pub allowed_mime_types: Option<Vec<String>>, // TODO: Look at https://crates.io/crates/infer to do this
// Example of things we can extend with:
// Switch the on for users that we know can/will connect with FTPS
//pub enforce_tls: bool,
/// The user's home directory relative to the storage back-end root
pub root: Option<PathBuf>,
}

impl User {
Expand All @@ -30,6 +30,7 @@ impl User {
account_enabled: true,
vfs_permissions: VfsOperations::all(),
allowed_mime_types: None,
root: None,
}
}
}
Expand All @@ -50,6 +51,12 @@ impl std::fmt::Display for User {
}
}

impl crate::storage::UserWithRoot for User {
fn user_root(&self) -> Option<PathBuf> {
self.root.clone()
}
}

bitflags! {
pub struct VfsOperations: u32 {
const MK_DIR = 0b00000001;
Expand Down Expand Up @@ -169,6 +176,7 @@ impl UserDetailProvider for JsonUserProvider {
})
}),
allowed_mime_types: None,
root: u.root.map(PathBuf::from),
}
})
}
Expand Down
17 changes: 11 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,19 @@ fn make_json_auth(m: &clap::ArgMatches) -> Result<LookupAuthenticator, String> {
}

// Creates the filesystem storage back-end
fn fs_storage_backend(log: &Logger, m: &clap::ArgMatches) -> Box<dyn (Fn() -> storage::RestrictingVfs) + Send + Sync> {
fn fs_storage_backend(
log: &Logger,
m: &clap::ArgMatches,
) -> Box<dyn (Fn() -> storage::RooterVfs<storage::RestrictingVfs, auth::User, storage::SbeMeta>) + Send + Sync> {
let p: PathBuf = m.value_of(args::ROOT_DIR).unwrap().into();
let sub_log = Arc::new(log.new(o!("module" => "storage")));
Box::new(move || storage::RestrictingVfs {
delegate: storage::ChoosingVfs {
inner: storage::InnerVfs::File(unftp_sbe_fs::Filesystem::new(p.clone())),
log: sub_log.clone(),
},
Box::new(move || {
storage::RooterVfs::new(storage::RestrictingVfs {
delegate: storage::ChoosingVfs {
inner: storage::InnerVfs::File(unftp_sbe_fs::Filesystem::new(p.clone())),
log: sub_log.clone(),
},
})
})
}

Expand Down
4 changes: 3 additions & 1 deletion src/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod choose;
mod restrict;
mod rooter;

pub use choose::{ChoosingVfs, InnerVfs};
pub use choose::{ChoosingVfs, InnerVfs, SbeMeta};
pub use restrict::RestrictingVfs;
pub use rooter::{RooterVfs, UserWithRoot};
Loading

0 comments on commit d7b931b

Please sign in to comment.