Skip to content

Commit 0f3cbb1

Browse files
committed
Add users restrictions per prefix
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
1 parent c957cde commit 0f3cbb1

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

src/main.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use std::{net::SocketAddr, path::PathBuf};
3030
use tokio::io::AsyncSeekExt;
3131
use tokio_util::io::ReaderStream;
3232
use tower::ServiceBuilder;
33+
use toml::Table;
3334

3435

3536
#[derive(Parser, Debug)]
@@ -270,6 +271,44 @@ fn heuristic_filetype(filename: String) -> String {
270271
}
271272
}
272273

274+
/*
275+
Example config.toml section:
276+
277+
[users]
278+
[users.alice]
279+
prefixes = ["/alice"]
280+
[users.bob]
281+
prefixes = ["/bob"]
282+
[users.admin]
283+
prefixes = [""]
284+
*/
285+
286+
fn verify_upload_permissions(owner: &str, path: &str) -> Result<(), String> {
287+
let cfg_content = get_config_content();
288+
let cfg: Table = toml::from_str(&cfg_content).unwrap();
289+
let users_r = cfg.get("users");
290+
let users = match users_r {
291+
Some(users) => users,
292+
None => {
293+
println!("No users section in config.toml, ignoring upload path restriction");
294+
return Ok(());
295+
}
296+
};
297+
let users_vec = users.as_array().unwrap();
298+
for user in users_vec {
299+
let user_name = user.get("name").unwrap().as_str().unwrap();
300+
let user_prefixes = user.get("prefixes").unwrap();
301+
let user_prefixes_vec = user_prefixes.as_array().unwrap();
302+
for prefix_value in user_prefixes_vec {
303+
let prefix = prefix_value.as_str().unwrap();
304+
if (path.starts_with(prefix) || prefix == "") && user_name == owner {
305+
return Ok(());
306+
}
307+
}
308+
}
309+
Err(format!("User {} has no upload permissions for path {}", owner, path))
310+
}
311+
273312
/*
274313
Upload file from user to remote storage
275314
TBD: Store file in cache as well?
@@ -304,6 +343,14 @@ async fn ax_post_file(headers: HeaderMap, mut multipart: Multipart) -> (StatusCo
304343
let mut file0: Vec<u8> = Vec::new();
305344
let mut file0_filename: String = "".to_string();
306345

346+
// verify upload permissions, some users have upload permissions only for certain prefix(path)
347+
// check config.toml for upload_prefixes
348+
match verify_upload_permissions(&owner, &path) {
349+
Ok(_) => (),
350+
Err(e) => return (StatusCode::FORBIDDEN, e.to_string().into_bytes()),
351+
}
352+
353+
307354
while let Some(field) = multipart.next_field().await.unwrap() {
308355
let name = field.name().unwrap().to_string();
309356
//let filename = field.file_name();

0 commit comments

Comments
 (0)