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
|
.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(
|
pub async fn get_permissions(
|
||||||
file_id: Uuid,
|
file_id: Uuid,
|
||||||
user_id: i32,
|
user_id: i32,
|
||||||
pool: &Pool,
|
pool: &Pool,
|
||||||
) -> sqlx::Result<PermissionType> {
|
) -> sqlx::Result<PermissionType> {
|
||||||
let record = sqlx::query!(
|
match get_folder_id(file_id, pool).await? {
|
||||||
"SELECT file_id FROM files JOIN folders ON files.folder_id = folders.folder_id WHERE file_id = $1 AND owner_id = $2",
|
Some(folder_id) => super::folder::get_permissions(folder_id, user_id, pool).await,
|
||||||
file_id,
|
None => Ok(PermissionType::default()),
|
||||||
user_id
|
}
|
||||||
)
|
|
||||||
.fetch_optional(pool)
|
|
||||||
.await?;
|
|
||||||
Ok(record.map(|_| PermissionType::Write).unwrap_or_default())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_name(file_id: Uuid, pool: &Pool) -> sqlx::Result<Option<String>> {
|
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 futures::TryStreamExt;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::Pool;
|
use crate::{db::permissions::PermissionRaw, Pool};
|
||||||
|
|
||||||
use super::permissions::PermissionType;
|
use super::permissions::PermissionType;
|
||||||
|
|
||||||
@ -12,16 +12,11 @@ pub async fn get_permissions(
|
|||||||
user_id: i32,
|
user_id: i32,
|
||||||
pool: &Pool,
|
pool: &Pool,
|
||||||
) -> sqlx::Result<PermissionType> {
|
) -> sqlx::Result<PermissionType> {
|
||||||
let permission = sqlx::query!(
|
let permission = sqlx::query_file!("sql/get_permissions_for_folder.sql", folder_id, user_id)
|
||||||
"SELECT folder_id FROM folders WHERE folder_id = $1 AND owner_id = $2",
|
|
||||||
folder_id,
|
|
||||||
user_id
|
|
||||||
)
|
|
||||||
.fetch_optional(pool)
|
.fetch_optional(pool)
|
||||||
.await?
|
.await?
|
||||||
.map(|_| PermissionType::Write)
|
.and_then(|record| record.permission_type);
|
||||||
.unwrap_or_default();
|
Ok(permission.into())
|
||||||
Ok(permission)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_names(folder_id: Uuid, pool: &Pool) -> sqlx::Result<HashSet<String>> {
|
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)]
|
use axum::http::StatusCode;
|
||||||
#[sqlx(type_name = "permission", rename_all = "lowercase")]
|
use futures::TryStreamExt as _;
|
||||||
pub(super) enum PermissionRaw {
|
use uuid::Uuid;
|
||||||
Read,
|
|
||||||
|
use crate::Pool;
|
||||||
|
|
||||||
|
#[derive(sqlx::Type, Debug)]
|
||||||
|
#[sqlx(type_name = "permission")]
|
||||||
|
#[sqlx(rename_all = "lowercase")]
|
||||||
|
pub enum PermissionRaw {
|
||||||
|
Read = 1,
|
||||||
Write,
|
Write,
|
||||||
Manage,
|
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 {
|
impl PermissionType {
|
||||||
pub fn can_read(self) -> bool {
|
pub fn can_read(self) -> bool {
|
||||||
self >= PermissionType::Read
|
self >= PermissionType::Read
|
||||||
@ -57,3 +75,32 @@ impl PermissionType {
|
|||||||
Ok(())
|
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
|
.storage
|
||||||
.write(params.file_id)
|
.write(params.file_id)
|
||||||
.await
|
.await
|
||||||
.handle_internal()?
|
.handle_internal()?
|
||||||
else {
|
.ok_or(StatusCode::NOT_FOUND)?;
|
||||||
return Err(StatusCode::NOT_FOUND);
|
|
||||||
};
|
|
||||||
|
|
||||||
let (hash, size) = match crate::FileStorage::write_to_file(&mut file, &mut field).await {
|
let (hash, size) = match crate::FileStorage::write_to_file(&mut file, &mut field).await {
|
||||||
Ok(values) => values,
|
Ok(values) => values,
|
||||||
|
Reference in New Issue
Block a user