-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move more things to domain and infra packages
This is in preparation for adding a REST or HTTP user detail provider. I'm moving code into the `domain` and `infra` modules. The `domain` module contains the traits to be implemented in the infra packages.
- Loading branch information
1 parent
a79f96c
commit 16a0b65
Showing
12 changed files
with
176 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
#![allow(dead_code)] | ||
|
||
/// The application name | ||
pub const NAME: &str = "unFTP"; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
//! The domain module contains code to be dependent upon elsewhere in this project. It | ||
//! should itself not depend on any modules in this project. | ||
pub mod events; | ||
pub mod user; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use libunftp::auth::UserDetail; | ||
use std::fmt::{Debug, Display, Formatter}; | ||
use std::path::PathBuf; | ||
use unftp_sbe_restrict::{UserWithPermissions, VfsOperations}; | ||
use unftp_sbe_rooter::UserWithRoot; | ||
|
||
/// The unFTP user details | ||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct User { | ||
pub username: String, | ||
pub name: Option<String>, | ||
pub surname: Option<String>, | ||
/// Tells whether this user can log in or not. | ||
pub account_enabled: bool, | ||
/// What FTP commands can the user perform | ||
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 | ||
/// The user's home directory relative to the storage back-end root | ||
pub root: Option<PathBuf>, | ||
} | ||
|
||
impl User { | ||
pub fn with_defaults(username: impl Into<String>) -> Self { | ||
User { | ||
username: username.into(), | ||
name: None, | ||
surname: None, | ||
account_enabled: true, | ||
vfs_permissions: VfsOperations::all(), | ||
allowed_mime_types: None, | ||
root: None, | ||
} | ||
} | ||
} | ||
|
||
impl UserDetail for User { | ||
fn account_enabled(&self) -> bool { | ||
self.account_enabled | ||
} | ||
} | ||
|
||
impl Display for User { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
write!( | ||
f, | ||
"User(username: {:?}, name: {:?}, surname: {:?})", | ||
self.username, self.name, self.surname | ||
) | ||
} | ||
} | ||
|
||
impl UserWithRoot for User { | ||
fn user_root(&self) -> Option<PathBuf> { | ||
self.root.clone() | ||
} | ||
} | ||
|
||
impl UserWithPermissions for User { | ||
fn permissions(&self) -> VfsOperations { | ||
self.vfs_permissions | ||
} | ||
} | ||
|
||
/// Implementation of UserDetailProvider can look up and provide FTP user account details from | ||
/// a source. | ||
pub trait UserDetailProvider: Debug { | ||
fn provide_user_detail(&self, username: &str) -> Option<User>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
//! Infra contains infrastructure specific implementations of things in the [`domain`](crate::domain) | ||
//! module. | ||
mod pubsub; | ||
mod workload_identity; | ||
|
||
pub mod usrdetail_json; | ||
|
||
pub use pubsub::PubsubEventDispatcher; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use crate::domain::user::{User, UserDetailProvider}; | ||
use serde::Deserialize; | ||
use std::path::PathBuf; | ||
use unftp_sbe_restrict::VfsOperations; | ||
|
||
/// A [`UserDetail`] provider that gets user details from a JSON file. | ||
#[derive(Debug, Deserialize)] | ||
pub struct JsonUserProvider { | ||
users: Vec<UserJsonObj>, | ||
} | ||
|
||
#[derive(Deserialize, Clone, Debug)] | ||
struct UserJsonObj { | ||
username: String, | ||
name: Option<String>, | ||
surname: Option<String>, | ||
vfs_perms: Option<Vec<String>>, | ||
#[allow(dead_code)] | ||
allowed_mime_types: Option<Vec<String>>, | ||
root: Option<String>, | ||
account_enabled: Option<bool>, | ||
} | ||
|
||
impl JsonUserProvider { | ||
pub fn from_json(json: &str) -> std::result::Result<JsonUserProvider, String> { | ||
let v: Vec<UserJsonObj> = serde_json::from_str(json).map_err(|e| format!("{:?}", e))?; | ||
Ok(JsonUserProvider { users: v }) | ||
} | ||
} | ||
|
||
impl UserDetailProvider for JsonUserProvider { | ||
fn provide_user_detail(&self, username: &str) -> Option<User> { | ||
self.users.iter().find(|u| u.username == username).map(|u| { | ||
let u = u.clone(); | ||
User { | ||
username: u.username, | ||
name: u.name, | ||
surname: u.surname, | ||
account_enabled: u.account_enabled.unwrap_or(true), | ||
vfs_permissions: u.vfs_perms.map_or(VfsOperations::all(), |p| { | ||
p.iter() | ||
.fold(VfsOperations::all(), |ops, s| match s.as_str() { | ||
"none" => VfsOperations::empty(), | ||
"all" => VfsOperations::all(), | ||
"-mkdir" => ops - VfsOperations::MK_DIR, | ||
"-rmdir" => ops - VfsOperations::RM_DIR, | ||
"-del" => ops - VfsOperations::DEL, | ||
"-ren" => ops - VfsOperations::RENAME, | ||
"-md5" => ops - VfsOperations::MD5, | ||
"-get" => ops - VfsOperations::GET, | ||
"-put" => ops - VfsOperations::PUT, | ||
"-list" => ops - VfsOperations::LIST, | ||
"+mkdir" => ops | VfsOperations::MK_DIR, | ||
"+rmdir" => ops | VfsOperations::RM_DIR, | ||
"+del" => ops | VfsOperations::DEL, | ||
"+ren" => ops | VfsOperations::RENAME, | ||
"+md5" => ops | VfsOperations::MD5, | ||
"+get" => ops | VfsOperations::GET, | ||
"+put" => ops | VfsOperations::PUT, | ||
"+list" => ops | VfsOperations::LIST, | ||
_ => ops, | ||
}) | ||
}), | ||
allowed_mime_types: None, | ||
root: u.root.map(PathBuf::from), | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.