feat: Implement album and person sharing with user search and a dedicated share dialog.
This commit is contained in:
@@ -65,7 +65,7 @@ pub struct PostgresMediaMetadata {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, sqlx::Type, PartialEq, Eq, Deserialize)]
|
||||
#[sqlx(rename_all = "lowercase")]
|
||||
#[sqlx(rename_all = "snake_case")]
|
||||
#[sqlx(type_name = "album_permission")]
|
||||
pub enum PostgresAlbumPermission {
|
||||
View,
|
||||
@@ -103,7 +103,7 @@ pub struct PostgresFaceRegion {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, sqlx::Type, PartialEq, Eq, Deserialize)]
|
||||
#[sqlx(rename_all = "lowercase")]
|
||||
#[sqlx(rename_all = "snake_case")]
|
||||
#[sqlx(type_name = "person_permission")]
|
||||
pub enum PostgresPersonPermission {
|
||||
View,
|
||||
|
||||
@@ -111,4 +111,61 @@ impl AlbumShareRepository for PostgresAlbumShareRepository {
|
||||
|
||||
Ok(result.exists.unwrap_or(false))
|
||||
}
|
||||
|
||||
async fn list_shares_for_album(
|
||||
&self,
|
||||
album_id: Uuid,
|
||||
) -> CoreResult<Vec<(libertas_core::models::User, AlbumPermission)>> {
|
||||
let rows = sqlx::query!(
|
||||
r#"
|
||||
SELECT
|
||||
u.id, u.username, u.email, u.hashed_password, u.created_at, u.updated_at,
|
||||
u.role, u.storage_quota, u.storage_used,
|
||||
ash.permission as "permission: PostgresAlbumPermission"
|
||||
FROM album_shares ash
|
||||
JOIN users u ON ash.user_id = u.id
|
||||
WHERE ash.album_id = $1
|
||||
"#,
|
||||
album_id
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await
|
||||
.map_err(|e| CoreError::Database(e.to_string()))?;
|
||||
|
||||
let result = rows
|
||||
.into_iter()
|
||||
.map(|row| {
|
||||
let user = crate::db_models::PostgresUser {
|
||||
id: row.id,
|
||||
username: row.username,
|
||||
email: row.email,
|
||||
hashed_password: row.hashed_password,
|
||||
created_at: row.created_at,
|
||||
updated_at: row.updated_at,
|
||||
role: row.role,
|
||||
storage_quota: row.storage_quota,
|
||||
storage_used: row.storage_used,
|
||||
}
|
||||
.into();
|
||||
(user, row.permission.into())
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
async fn remove_share(&self, album_id: Uuid, user_id: Uuid) -> CoreResult<()> {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
DELETE FROM album_shares
|
||||
WHERE album_id = $1 AND user_id = $2
|
||||
"#,
|
||||
album_id,
|
||||
user_id
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(|e| CoreError::Database(e.to_string()))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use libertas_core::{
|
||||
models::{Person, PersonPermission},
|
||||
repositories::PersonShareRepository,
|
||||
};
|
||||
use sqlx::{types::Uuid, PgPool};
|
||||
use sqlx::{PgPool, types::Uuid};
|
||||
|
||||
use crate::db_models::{PostgresPersonPermission, PostgresPersonShared};
|
||||
|
||||
@@ -103,4 +103,46 @@ impl PersonShareRepository for PostgresPersonShareRepository {
|
||||
.map(PostgresPersonShared::into)
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_shares_for_person(
|
||||
&self,
|
||||
person_id: Uuid,
|
||||
) -> CoreResult<Vec<(libertas_core::models::User, PersonPermission)>> {
|
||||
let rows = sqlx::query!(
|
||||
r#"
|
||||
SELECT
|
||||
u.id, u.username, u.email, u.hashed_password, u.created_at, u.updated_at,
|
||||
u.role, u.storage_quota, u.storage_used,
|
||||
ps.permission as "permission: PostgresPersonPermission"
|
||||
FROM person_shares ps
|
||||
JOIN users u ON ps.user_id = u.id
|
||||
WHERE ps.person_id = $1
|
||||
"#,
|
||||
person_id
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await
|
||||
.map_err(|e| CoreError::Database(e.to_string()))?;
|
||||
|
||||
let result = rows
|
||||
.into_iter()
|
||||
.map(|row| {
|
||||
let user = crate::db_models::PostgresUser {
|
||||
id: row.id,
|
||||
username: row.username,
|
||||
email: row.email,
|
||||
hashed_password: row.hashed_password,
|
||||
created_at: row.created_at,
|
||||
updated_at: row.updated_at,
|
||||
role: row.role,
|
||||
storage_quota: row.storage_quota,
|
||||
storage_used: row.storage_used,
|
||||
}
|
||||
.into();
|
||||
(user, row.permission.into())
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,27 @@ impl UserRepository for PostgresUserRepository {
|
||||
async fn update_storage_used(&self, user_id: Uuid, bytes: i64) -> CoreResult<()> {
|
||||
Self::update_storage_used_internal(&self.pool, user_id, bytes).await
|
||||
}
|
||||
|
||||
async fn search_users(&self, query: &str) -> CoreResult<Vec<User>> {
|
||||
let pattern = format!("%{}%", query);
|
||||
let pg_users = sqlx::query_as!(
|
||||
PostgresUser,
|
||||
r#"
|
||||
SELECT
|
||||
id, username, email, hashed_password, created_at, updated_at,
|
||||
role, storage_quota, storage_used
|
||||
FROM users
|
||||
WHERE username ILIKE $1 OR email ILIKE $1
|
||||
LIMIT 10
|
||||
"#,
|
||||
pattern
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await
|
||||
.map_err(|e| CoreError::Database(e.to_string()))?;
|
||||
|
||||
Ok(pg_users.into_iter().map(|u| u.into()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -165,4 +186,9 @@ impl UserRepository for SqliteUserRepository {
|
||||
println!("SQLITE REPO: Updating user storage used");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn search_users(&self, _query: &str) -> CoreResult<Vec<User>> {
|
||||
println!("SQLITE REPO: Searching users");
|
||||
Ok(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user