cleanup code and queries

This commit is contained in:
Mateusz Gruszczyński
2026-07-24 11:37:04 +02:00
parent 33b4667e42
commit 27243299cd
3 changed files with 67 additions and 29 deletions
+2 -2
View File
@@ -1132,7 +1132,7 @@ pub async fn create_resource_access_token(
let token = hex::encode(bytes);
let expires_at =
(Utc::now() + Duration::days(state.anonymous_access_token_ttl_days)).to_rfc3339();
sqlx::query(queries::get(state.db.kind(), "INSERT INTO resource_access_tokens (token_hash, resource_kind, resource_slug, expires_at) VALUES (?, ?, ?, ?)"))
sqlx::query(queries::get(state.db.kind(), queries::RESOURCE_ACCESS_TOKENS_INSERT))
.bind(hash_access_token(&token))
.bind(kind)
.bind(slug)
@@ -1161,7 +1161,7 @@ pub async fn verify_resource_access_token(
{
return Ok(true);
}
let count: i64 = sqlx::query_scalar(queries::get(state.db.kind(), "SELECT COUNT(*) FROM resource_access_tokens WHERE token_hash = ? AND resource_kind = ? AND resource_slug = ? AND expires_at > ?"))
let count: i64 = sqlx::query_scalar(queries::get(state.db.kind(), queries::RESOURCE_ACCESS_TOKENS_VALID_COUNT))
.bind(hash_access_token(token))
.bind(kind)
.bind(slug)
+25 -27
View File
@@ -466,7 +466,7 @@ pub async fn update_resource(
.map_err(AuthError::database)?;
sqlx::query(queries::get(
state.db.kind(),
"DELETE FROM resource_access_tokens WHERE resource_kind = ? AND resource_slug = ?",
queries::RESOURCE_ACCESS_TOKENS_DELETE_BY_RESOURCE,
))
.bind(req.kind.as_str())
.bind(req.slug.trim())
@@ -490,7 +490,7 @@ pub async fn delete_resource(
};
sqlx::query(queries::get(
state.db.kind(),
"DELETE FROM resource_access_tokens WHERE resource_kind = ? AND resource_slug = ?",
queries::RESOURCE_ACCESS_TOKENS_DELETE_BY_RESOURCE,
))
.bind(req.kind.as_str())
.bind(req.slug.trim())
@@ -553,14 +553,12 @@ pub async fn set_resource_privacy(
) -> Result<Json<serde_json::Value>, AuthError> {
let user = require_user(&state, &headers).await?;
ensure_owner(&state, user.id, &req.kind, &req.slug).await?;
let table = match req.kind.as_str() {
"workspace" => "workspaces",
"pad" => "pads",
let query = match req.kind.as_str() {
"workspace" => queries::USER_SET_WORKSPACE_PRIVACY,
"pad" => queries::USER_SET_PAD_PRIVACY,
_ => return Err(AuthError::bad_request("Unknown resource type.")),
};
let query =
format!("UPDATE {table} SET is_private = ?, updated_at = CURRENT_TIMESTAMP WHERE slug = ?");
sqlx::query(&query)
sqlx::query(queries::get(state.db.kind(), query))
.bind(req.private)
.bind(req.slug.trim())
.execute(state.db.pool())
@@ -604,16 +602,16 @@ pub async fn share_resource_users(
continue;
}
sqlx::query(queries::get(state.db.kind(), "DELETE FROM resource_permissions WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?"))
sqlx::query(queries::get(state.db.kind(), queries::RESOURCE_PERMISSION_DELETE_USER))
.bind(&req.kind).bind(req.slug.trim()).bind(user.id).execute(state.db.pool()).await.map_err(AuthError::database)?;
sqlx::query(queries::get(state.db.kind(), "DELETE FROM resource_share_invitations WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?"))
sqlx::query(queries::get(state.db.kind(), queries::SHARE_INVITATION_DELETE_USER))
.bind(&req.kind).bind(req.slug.trim()).bind(user.id).execute(state.db.pool()).await.map_err(AuthError::database)?;
if state.share_confirmation_required {
let token = random_token();
let token_hash = hash_token(&token);
let expires_at = (Utc::now() + Duration::days(7)).to_rfc3339();
sqlx::query(queries::get(state.db.kind(), "INSERT INTO resource_share_invitations (token_hash, resource_kind, resource_slug, user_id, permission, created_by, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?)"))
sqlx::query(queries::get(state.db.kind(), queries::SHARE_INVITATION_INSERT))
.bind(&token_hash).bind(&req.kind).bind(req.slug.trim()).bind(user.id).bind(permission).bind(owner.id).bind(&expires_at)
.execute(state.db.pool()).await.map_err(AuthError::database)?;
if let Err(error) = send_share_invitation(
@@ -629,7 +627,7 @@ pub async fn share_resource_users(
{
let _ = sqlx::query(queries::get(
state.db.kind(),
"DELETE FROM resource_share_invitations WHERE token_hash = ?",
queries::SHARE_INVITATION_DELETE_TOKEN,
))
.bind(&token_hash)
.execute(state.db.pool())
@@ -637,7 +635,7 @@ pub async fn share_resource_users(
return Err(error);
}
} else {
sqlx::query(queries::get(state.db.kind(), "INSERT INTO resource_permissions (resource_kind, resource_slug, user_id, permission) VALUES (?, ?, ?, ?)"))
sqlx::query(queries::get(state.db.kind(), queries::RESOURCE_PERMISSION_INSERT))
.bind(&req.kind).bind(req.slug.trim()).bind(user.id).bind(permission).execute(state.db.pool()).await.map_err(AuthError::database)?;
}
}
@@ -657,7 +655,7 @@ pub async fn accept_share_invitation(
AxumPath(token): AxumPath<String>,
) -> Result<Redirect, AuthError> {
let token_hash = hash_token(token.trim());
let row: Option<(String, String, i64, String, String, Option<String>)> = sqlx::query_as(queries::get(state.db.kind(), "SELECT resource_kind, resource_slug, user_id, permission, expires_at, accepted_at FROM resource_share_invitations WHERE token_hash = ?"))
let row: Option<(String, String, i64, String, String, Option<String>)> = sqlx::query_as(queries::get(state.db.kind(), queries::SHARE_INVITATION_FIND_TOKEN))
.bind(&token_hash).fetch_optional(state.db.pool()).await.map_err(AuthError::database)?;
let (kind, slug, user_id, permission, expires_at, accepted_at) = row.ok_or_else(|| {
AuthError::bad_request("The sharing invitation is invalid or has expired.")
@@ -672,13 +670,13 @@ pub async fn accept_share_invitation(
));
}
let mut tx = state.db.pool().begin().await.map_err(AuthError::database)?;
sqlx::query(queries::get(state.db.kind(), "DELETE FROM resource_permissions WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?"))
sqlx::query(queries::get(state.db.kind(), queries::RESOURCE_PERMISSION_DELETE_USER))
.bind(&kind).bind(&slug).bind(user_id).execute(&mut *tx).await.map_err(AuthError::database)?;
sqlx::query(queries::get(state.db.kind(), "INSERT INTO resource_permissions (resource_kind, resource_slug, user_id, permission) VALUES (?, ?, ?, ?)"))
sqlx::query(queries::get(state.db.kind(), queries::RESOURCE_PERMISSION_INSERT))
.bind(&kind).bind(&slug).bind(user_id).bind(&permission).execute(&mut *tx).await.map_err(AuthError::database)?;
sqlx::query(queries::get(
state.db.kind(),
"UPDATE resource_share_invitations SET accepted_at = ? WHERE token_hash = ?",
queries::SHARE_INVITATION_ACCEPT,
))
.bind(Utc::now().to_rfc3339())
.bind(&token_hash)
@@ -704,9 +702,9 @@ pub async fn remove_resource_user(
ensure_owner(&state, owner.id, &req.kind, &req.slug).await?;
let email = normalize(&req.email);
if let Some(user) = find_user_by_email(&state, &email).await? {
sqlx::query(queries::get(state.db.kind(), "DELETE FROM resource_permissions WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?"))
sqlx::query(queries::get(state.db.kind(), queries::RESOURCE_PERMISSION_DELETE_USER))
.bind(&req.kind).bind(req.slug.trim()).bind(user.id).execute(state.db.pool()).await.map_err(AuthError::database)?;
sqlx::query(queries::get(state.db.kind(), "DELETE FROM resource_share_invitations WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?"))
sqlx::query(queries::get(state.db.kind(), queries::SHARE_INVITATION_DELETE_USER))
.bind(&req.kind).bind(req.slug.trim()).bind(user.id).execute(state.db.pool()).await.map_err(AuthError::database)?;
}
Ok(Json(serde_json::json!({"ok":true})))
@@ -725,11 +723,11 @@ pub async fn resource_sharing(
.get("slug")
.ok_or_else(|| AuthError::bad_request("Missing slug."))?;
ensure_owner(&state, owner.id, kind, slug).await?;
let users: Vec<(String,String,String)> = sqlx::query_as(queries::get(state.db.kind(), "SELECT u.email, u.nickname, rp.permission FROM resource_permissions rp JOIN users u ON u.id = rp.user_id WHERE rp.resource_kind = ? AND rp.resource_slug = ? ORDER BY u.email"))
let users: Vec<(String,String,String)> = sqlx::query_as(queries::get(state.db.kind(), queries::RESOURCE_SHARING_USERS))
.bind(kind).bind(slug).fetch_all(state.db.pool()).await.map_err(AuthError::database)?;
let links: Vec<(String,String,Option<String>,String)> = sqlx::query_as(queries::get(state.db.kind(), "SELECT token_hash, permission, expires_at, created_at FROM resource_share_links WHERE resource_kind = ? AND resource_slug = ? AND revoked_at IS NULL ORDER BY created_at DESC"))
let links: Vec<(String,String,Option<String>,String)> = sqlx::query_as(queries::get(state.db.kind(), queries::RESOURCE_SHARING_LINKS))
.bind(kind).bind(slug).fetch_all(state.db.pool()).await.map_err(AuthError::database)?;
let pending: Vec<(String,String,String,String)> = sqlx::query_as(queries::get(state.db.kind(), "SELECT u.email, u.nickname, i.permission, i.expires_at FROM resource_share_invitations i JOIN users u ON u.id = i.user_id WHERE i.resource_kind = ? AND i.resource_slug = ? AND i.accepted_at IS NULL ORDER BY u.email"))
let pending: Vec<(String,String,String,String)> = sqlx::query_as(queries::get(state.db.kind(), queries::RESOURCE_SHARING_PENDING))
.bind(kind).bind(slug).fetch_all(state.db.pool()).await.map_err(AuthError::database)?;
Ok(Json(
serde_json::json!({"users":users.into_iter().map(|(email,nickname,permission)|serde_json::json!({"email":email,"nickname":nickname,"permission":permission})).collect::<Vec<_>>(), "pending":pending.into_iter().map(|(email,nickname,permission,expires_at)|serde_json::json!({"email":email,"nickname":nickname,"permission":permission,"expires_at":expires_at})).collect::<Vec<_>>(), "links":links.into_iter().map(|(token,permission,expires_at,created_at)|serde_json::json!({"token":token,"permission":permission,"expires_at":expires_at,"created_at":created_at})).collect::<Vec<_>>() }),
@@ -747,7 +745,7 @@ pub async fn create_share_link(
validate_share_expiration(req.expires_at.as_deref())?;
let token = random_token();
let token_hash = hash_token(&token);
sqlx::query(queries::get(state.db.kind(), "INSERT INTO resource_share_links (token_hash, resource_kind, resource_slug, permission, expires_at, created_by) VALUES (?, ?, ?, ?, ?, ?)"))
sqlx::query(queries::get(state.db.kind(), queries::SHARE_LINK_INSERT))
.bind(token_hash).bind(&req.kind).bind(req.slug.trim()).bind(permission).bind(&req.expires_at).bind(owner.id).execute(state.db.pool()).await.map_err(AuthError::database)?;
let base = if req.kind == "workspace" {
format!("/w/{}", req.slug.trim())
@@ -768,7 +766,7 @@ pub async fn update_share_link(
ensure_owner(&state, owner.id, &req.kind, &req.slug).await?;
let permission = validate_permission(&req.permission)?;
validate_share_expiration(req.expires_at.as_deref())?;
let result = sqlx::query(queries::get(state.db.kind(), "UPDATE resource_share_links SET permission = ?, expires_at = ? WHERE token_hash = ? AND resource_kind = ? AND resource_slug = ? AND revoked_at IS NULL"))
let result = sqlx::query(queries::get(state.db.kind(), queries::SHARE_LINK_UPDATE))
.bind(permission).bind(&req.expires_at).bind(req.token.trim()).bind(&req.kind).bind(req.slug.trim()).execute(state.db.pool()).await.map_err(AuthError::database)?;
if result.rows_affected() == 0 {
return Err(AuthError::bad_request(
@@ -787,7 +785,7 @@ pub async fn revoke_share_link(
) -> Result<Json<serde_json::Value>, AuthError> {
let owner = require_user(&state, &headers).await?;
ensure_owner(&state, owner.id, &req.kind, &req.slug).await?;
sqlx::query(queries::get(state.db.kind(), "UPDATE resource_share_links SET revoked_at = ? WHERE token_hash = ? AND resource_kind = ? AND resource_slug = ?"))
sqlx::query(queries::get(state.db.kind(), queries::SHARE_LINK_REVOKE))
.bind(Utc::now().to_rfc3339()).bind(req.token.trim()).bind(&req.kind).bind(req.slug.trim()).execute(state.db.pool()).await.map_err(AuthError::database)?;
Ok(Json(serde_json::json!({"ok":true})))
}
@@ -826,12 +824,12 @@ pub async fn resource_permission(
if owns {
return Ok(Some("rw".into()));
}
let permission: Option<String> = sqlx::query_scalar(queries::get(state.db.kind(), "SELECT permission FROM resource_permissions WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?"))
let permission: Option<String> = sqlx::query_scalar(queries::get(state.db.kind(), queries::RESOURCE_PERMISSION_BY_USER))
.bind(kind).bind(slug).bind(user.id).fetch_optional(state.db.pool()).await.map_err(AuthError::database)?;
return Ok(permission);
}
let now = Utc::now().to_rfc3339();
let permission: Option<String> = sqlx::query_scalar(queries::get(state.db.kind(), "SELECT permission FROM resource_share_links WHERE token_hash = ? AND resource_kind = ? AND resource_slug = ? AND revoked_at IS NULL AND (expires_at IS NULL OR expires_at > ?)"))
let permission: Option<String> = sqlx::query_scalar(queries::get(state.db.kind(), queries::SHARE_LINK_PERMISSION))
.bind(hash_token(token)).bind(kind).bind(slug).bind(now).fetch_optional(state.db.pool()).await.map_err(AuthError::database)?;
Ok(permission)
}
+40
View File
@@ -61,6 +61,46 @@ pub const USER_SET_WORKSPACE_PASSWORD: &str =
"UPDATE workspaces SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE slug = ?";
pub const USER_SET_PAD_PASSWORD: &str =
"UPDATE pads SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE slug = ?";
pub const USER_SET_WORKSPACE_PRIVACY: &str =
"UPDATE workspaces SET is_private = ?, updated_at = CURRENT_TIMESTAMP WHERE slug = ?";
pub const USER_SET_PAD_PRIVACY: &str =
"UPDATE pads SET is_private = ?, updated_at = CURRENT_TIMESTAMP WHERE slug = ?";
pub const RESOURCE_ACCESS_TOKENS_DELETE_BY_RESOURCE: &str =
"DELETE FROM resource_access_tokens WHERE resource_kind = ? AND resource_slug = ?";
pub const RESOURCE_ACCESS_TOKENS_INSERT: &str =
"INSERT INTO resource_access_tokens (token_hash, resource_kind, resource_slug, expires_at) VALUES (?, ?, ?, ?)";
pub const RESOURCE_ACCESS_TOKENS_VALID_COUNT: &str =
"SELECT COUNT(*) FROM resource_access_tokens WHERE token_hash = ? AND resource_kind = ? AND resource_slug = ? AND expires_at > ?";
pub const RESOURCE_PERMISSION_DELETE_USER: &str =
"DELETE FROM resource_permissions WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?";
pub const RESOURCE_PERMISSION_INSERT: &str =
"INSERT INTO resource_permissions (resource_kind, resource_slug, user_id, permission) VALUES (?, ?, ?, ?)";
pub const SHARE_INVITATION_DELETE_USER: &str =
"DELETE FROM resource_share_invitations WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?";
pub const SHARE_INVITATION_INSERT: &str =
"INSERT INTO resource_share_invitations (token_hash, resource_kind, resource_slug, user_id, permission, created_by, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?)";
pub const SHARE_INVITATION_DELETE_TOKEN: &str =
"DELETE FROM resource_share_invitations WHERE token_hash = ?";
pub const SHARE_INVITATION_FIND_TOKEN: &str =
"SELECT resource_kind, resource_slug, user_id, permission, expires_at, accepted_at FROM resource_share_invitations WHERE token_hash = ?";
pub const SHARE_INVITATION_ACCEPT: &str =
"UPDATE resource_share_invitations SET accepted_at = ? WHERE token_hash = ?";
pub const RESOURCE_SHARING_USERS: &str =
"SELECT u.email, u.nickname, rp.permission FROM resource_permissions rp JOIN users u ON u.id = rp.user_id WHERE rp.resource_kind = ? AND rp.resource_slug = ? ORDER BY u.email";
pub const RESOURCE_SHARING_LINKS: &str =
"SELECT token_hash, permission, expires_at, created_at FROM resource_share_links WHERE resource_kind = ? AND resource_slug = ? AND revoked_at IS NULL ORDER BY created_at DESC";
pub const RESOURCE_SHARING_PENDING: &str =
"SELECT u.email, u.nickname, i.permission, i.expires_at FROM resource_share_invitations i JOIN users u ON u.id = i.user_id WHERE i.resource_kind = ? AND i.resource_slug = ? AND i.accepted_at IS NULL ORDER BY u.email";
pub const SHARE_LINK_INSERT: &str =
"INSERT INTO resource_share_links (token_hash, resource_kind, resource_slug, permission, expires_at, created_by) VALUES (?, ?, ?, ?, ?, ?)";
pub const SHARE_LINK_UPDATE: &str =
"UPDATE resource_share_links SET permission = ?, expires_at = ? WHERE token_hash = ? AND resource_kind = ? AND resource_slug = ? AND revoked_at IS NULL";
pub const SHARE_LINK_REVOKE: &str =
"UPDATE resource_share_links SET revoked_at = ? WHERE token_hash = ? AND resource_kind = ? AND resource_slug = ?";
pub const RESOURCE_PERMISSION_BY_USER: &str =
"SELECT permission FROM resource_permissions WHERE resource_kind = ? AND resource_slug = ? AND user_id = ?";
pub const SHARE_LINK_PERMISSION: &str =
"SELECT permission FROM resource_share_links WHERE token_hash = ? AND resource_kind = ? AND resource_slug = ? AND revoked_at IS NULL AND (expires_at IS NULL OR expires_at > ?)";
pub const Q001: &str = "SELECT id, slug, title, password_hash, created_at, updated_at, CAST(CASE WHEN is_private THEN 1 ELSE 0 END AS BIGINT) AS is_private FROM workspaces WHERE slug = ?";
pub const Q002: &str = "INSERT INTO workspaces (slug, title, password_hash) VALUES (?, ?, ?)";