Started work on permissions
This commit is contained in:
parent
3ed30f0d9b
commit
ffbb2a8bbc
6
build.rs
Normal file
6
build.rs
Normal file
@ -0,0 +1,6 @@
|
||||
// generated by `sqlx migrate build-script`
|
||||
fn main() {
|
||||
// trigger recompilation when a new migration is added
|
||||
println!("cargo:rerun-if-changed=migrations");
|
||||
println!("cargo:rerun-if-changed=sql");
|
||||
}
|
8
sql/get_all_permissions_for_folder.sql
Normal file
8
sql/get_all_permissions_for_folder.sql
Normal file
@ -0,0 +1,8 @@
|
||||
SELECT
|
||||
username,
|
||||
permission_type as "permission_type: PermissionRaw"
|
||||
FROM
|
||||
permissions
|
||||
INNER JOIN users ON permissions.user_id = users.user_id
|
||||
WHERE
|
||||
folder_id = $1
|
15
sql/get_permissions_for_folder.sql
Normal file
15
sql/get_permissions_for_folder.sql
Normal file
@ -0,0 +1,15 @@
|
||||
SELECT
|
||||
permission_type as "permission_type: PermissionRaw"
|
||||
FROM
|
||||
permissions
|
||||
WHERE
|
||||
folder_id = $1
|
||||
AND user_id = $2
|
||||
UNION
|
||||
SELECT
|
||||
'manage' as "permission_type: PermissionRaw"
|
||||
FROM
|
||||
folders
|
||||
WHERE
|
||||
folder_id = $1
|
||||
AND owner_id = $2
|
24
sql/insert_permission.sql
Normal file
24
sql/insert_permission.sql
Normal file
@ -0,0 +1,24 @@
|
||||
WITH RECURSIVE folder_hierarchy AS (
|
||||
-- Start with the given directory
|
||||
SELECT
|
||||
folder_id
|
||||
FROM
|
||||
folders
|
||||
WHERE
|
||||
folder_id = $1
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- Recursively find all subdirectories
|
||||
SELECT
|
||||
f.folder_id
|
||||
FROM
|
||||
folders f
|
||||
INNER JOIN
|
||||
folder_hierarchy fh ON f.parent_folder_id = fh.folder_id
|
||||
)
|
||||
INSERT INTO permissions(user_id, folder_id, permission_type)
|
||||
SELECT $2::integer as user_id, fh.folder_id::UUID as folder_id, $3
|
||||
FROM folder_hierarchy fh
|
||||
ON CONFLICT (user_id, folder_id) DO UPDATE
|
||||
SET permission_type = $3
|
@ -47,19 +47,23 @@ pub async fn get_files(folder_id: Uuid, pool: &Pool) -> sqlx::Result<Vec<FileWit
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_folder_id(file_id: Uuid, pool: &Pool) -> sqlx::Result<Option<Uuid>> {
|
||||
let uuid = sqlx::query!("SELECT folder_id FROM files WHERE file_id = $1", file_id)
|
||||
.fetch_optional(pool)
|
||||
.await?
|
||||
.map(|record| record.folder_id);
|
||||
Ok(uuid)
|
||||
}
|
||||
|
||||
pub async fn get_permissions(
|
||||
file_id: Uuid,
|
||||
user_id: i32,
|
||||
pool: &Pool,
|
||||
) -> sqlx::Result<PermissionType> {
|
||||
let record = sqlx::query!(
|
||||
"SELECT file_id FROM files JOIN folders ON files.folder_id = folders.folder_id WHERE file_id = $1 AND owner_id = $2",
|
||||
file_id,
|
||||
user_id
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await?;
|
||||
Ok(record.map(|_| PermissionType::Write).unwrap_or_default())
|
||||
match get_folder_id(file_id, pool).await? {
|
||||
Some(folder_id) => super::folder::get_permissions(folder_id, user_id, pool).await,
|
||||
None => Ok(PermissionType::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_name(file_id: Uuid, pool: &Pool) -> sqlx::Result<Option<String>> {
|
||||
|
@ -3,7 +3,7 @@ use std::collections::HashSet;
|
||||
use futures::TryStreamExt;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::Pool;
|
||||
use crate::{db::permissions::PermissionRaw, Pool};
|
||||
|
||||
use super::permissions::PermissionType;
|
||||
|
||||
@ -12,16 +12,11 @@ pub async fn get_permissions(
|
||||
user_id: i32,
|
||||
pool: &Pool,
|
||||
) -> sqlx::Result<PermissionType> {
|
||||
let permission = sqlx::query!(
|
||||
"SELECT folder_id FROM folders WHERE folder_id = $1 AND owner_id = $2",
|
||||
folder_id,
|
||||
user_id
|
||||
)
|
||||
let permission = sqlx::query_file!("sql/get_permissions_for_folder.sql", folder_id, user_id)
|
||||
.fetch_optional(pool)
|
||||
.await?
|
||||
.map(|_| PermissionType::Write)
|
||||
.unwrap_or_default();
|
||||
Ok(permission)
|
||||
.and_then(|record| record.permission_type);
|
||||
Ok(permission.into())
|
||||
}
|
||||
|
||||
pub async fn get_names(folder_id: Uuid, pool: &Pool) -> sqlx::Result<HashSet<String>> {
|
||||
|
@ -1,9 +1,16 @@
|
||||
use axum::http::StatusCode;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(sqlx::Type)]
|
||||
#[sqlx(type_name = "permission", rename_all = "lowercase")]
|
||||
pub(super) enum PermissionRaw {
|
||||
Read,
|
||||
use axum::http::StatusCode;
|
||||
use futures::TryStreamExt as _;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::Pool;
|
||||
|
||||
#[derive(sqlx::Type, Debug)]
|
||||
#[sqlx(type_name = "permission")]
|
||||
#[sqlx(rename_all = "lowercase")]
|
||||
pub enum PermissionRaw {
|
||||
Read = 1,
|
||||
Write,
|
||||
Manage,
|
||||
}
|
||||
@ -29,6 +36,17 @@ impl From<Option<PermissionRaw>> for PermissionType {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PermissionType> for PermissionRaw {
|
||||
fn from(value: PermissionType) -> Self {
|
||||
match value {
|
||||
PermissionType::Manage => Self::Manage,
|
||||
PermissionType::Write => Self::Write,
|
||||
PermissionType::Read => Self::Read,
|
||||
PermissionType::NoPermission => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PermissionType {
|
||||
pub fn can_read(self) -> bool {
|
||||
self >= PermissionType::Read
|
||||
@ -57,3 +75,32 @@ impl PermissionType {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn insert_permissions(
|
||||
user_id: i32,
|
||||
folder_id: Uuid,
|
||||
permission_type: PermissionType,
|
||||
pool: &Pool,
|
||||
) -> sqlx::Result<()> {
|
||||
let permission_type = PermissionRaw::from(permission_type);
|
||||
sqlx::query_file!(
|
||||
"sql/insert_permission.sql",
|
||||
folder_id,
|
||||
user_id,
|
||||
permission_type as PermissionRaw
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
pub async fn get_permissions_for_folder(
|
||||
folder_id: Uuid,
|
||||
pool: &Pool,
|
||||
) -> sqlx::Result<HashMap<String, PermissionType>> {
|
||||
sqlx::query_file!("sql/get_all_permissions_for_folder.sql", folder_id)
|
||||
.fetch(pool)
|
||||
.map_ok(|record| (record.username, Some(record.permission_type).into()))
|
||||
.try_collect()
|
||||
.await
|
||||
}
|
||||
|
@ -27,14 +27,12 @@ pub async fn modify(
|
||||
}
|
||||
};
|
||||
|
||||
let Some(mut file) = state
|
||||
let mut file = state
|
||||
.storage
|
||||
.write(params.file_id)
|
||||
.await
|
||||
.handle_internal()?
|
||||
else {
|
||||
return Err(StatusCode::NOT_FOUND);
|
||||
};
|
||||
.ok_or(StatusCode::NOT_FOUND)?;
|
||||
|
||||
let (hash, size) = match crate::FileStorage::write_to_file(&mut file, &mut field).await {
|
||||
Ok(values) => values,
|
||||
|
Reference in New Issue
Block a user