mirror of
https://tangled.org/tranquil.farm/tranquil-pds
synced 2026-09-11 04:36:05 +00:00
Misc fixes for blobs and invites
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use crate::auth::{ServiceTokenVerifier, is_service_token};
|
||||
use crate::delegation::{self, DelegationActionType};
|
||||
use crate::state::AppState;
|
||||
use crate::util::get_max_blob_size;
|
||||
use axum::body::Bytes;
|
||||
use axum::{
|
||||
Json,
|
||||
@@ -15,9 +16,6 @@ use serde_json::json;
|
||||
use sha2::{Digest, Sha256};
|
||||
use tracing::{debug, error};
|
||||
|
||||
const MAX_BLOB_SIZE: usize = 10_000_000_000;
|
||||
const MAX_VIDEO_BLOB_SIZE: usize = 10_000_000_000;
|
||||
|
||||
pub async fn upload_blob(
|
||||
State(state): State<AppState>,
|
||||
headers: axum::http::HeaderMap,
|
||||
@@ -38,7 +36,7 @@ pub async fn upload_blob(
|
||||
|
||||
let is_service_auth = is_service_token(&token);
|
||||
|
||||
let (did, is_migration, controller_did) = if is_service_auth {
|
||||
let (did, _is_migration, controller_did) = if is_service_auth {
|
||||
debug!("Verifying service token for blob upload");
|
||||
let verifier = ServiceTokenVerifier::new();
|
||||
match verifier
|
||||
@@ -94,11 +92,7 @@ pub async fn upload_blob(
|
||||
}
|
||||
};
|
||||
|
||||
let max_size = if is_service_auth || is_migration {
|
||||
MAX_VIDEO_BLOB_SIZE
|
||||
} else {
|
||||
MAX_BLOB_SIZE
|
||||
};
|
||||
let max_size = get_max_blob_size();
|
||||
|
||||
if body.len() > max_size {
|
||||
return (
|
||||
|
||||
@@ -46,14 +46,14 @@ pub struct CreateInviteCodeOutput {
|
||||
|
||||
pub async fn create_invite_code(
|
||||
State(state): State<AppState>,
|
||||
BearerAuthAdmin(_auth_user): BearerAuthAdmin,
|
||||
BearerAuthAdmin(auth_user): BearerAuthAdmin,
|
||||
Json(input): Json<CreateInviteCodeInput>,
|
||||
) -> Response {
|
||||
if input.use_count < 1 {
|
||||
return ApiError::InvalidRequest("useCount must be at least 1".into()).into_response();
|
||||
}
|
||||
|
||||
let for_account = input.for_account.unwrap_or_else(|| "admin".to_string());
|
||||
let for_account = input.for_account.unwrap_or_else(|| auth_user.did.clone());
|
||||
let code = gen_invite_code();
|
||||
|
||||
match sqlx::query!(
|
||||
@@ -101,7 +101,7 @@ pub struct AccountCodes {
|
||||
|
||||
pub async fn create_invite_codes(
|
||||
State(state): State<AppState>,
|
||||
BearerAuthAdmin(_auth_user): BearerAuthAdmin,
|
||||
BearerAuthAdmin(auth_user): BearerAuthAdmin,
|
||||
Json(input): Json<CreateInviteCodesInput>,
|
||||
) -> Response {
|
||||
if input.use_count < 1 {
|
||||
@@ -112,7 +112,7 @@ pub async fn create_invite_codes(
|
||||
let for_accounts = input
|
||||
.for_accounts
|
||||
.filter(|v| !v.is_empty())
|
||||
.unwrap_or_else(|| vec!["admin".to_string()]);
|
||||
.unwrap_or_else(|| vec![auth_user.did.clone()]);
|
||||
|
||||
let admin_user_id = match sqlx::query_scalar!(
|
||||
"SELECT id FROM users WHERE is_admin = true LIMIT 1"
|
||||
@@ -184,6 +184,8 @@ pub struct InviteCode {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InviteCodeUse {
|
||||
pub used_by: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub used_by_handle: Option<String>,
|
||||
pub used_at: String,
|
||||
}
|
||||
|
||||
@@ -238,7 +240,7 @@ pub async fn get_account_invite_codes(
|
||||
|
||||
let uses = sqlx::query!(
|
||||
r#"
|
||||
SELECT u.did, icu.used_at
|
||||
SELECT u.did, u.handle, icu.used_at
|
||||
FROM invite_code_uses icu
|
||||
JOIN users u ON icu.used_by_user = u.id
|
||||
WHERE icu.code = $1
|
||||
@@ -253,6 +255,7 @@ pub async fn get_account_invite_codes(
|
||||
.iter()
|
||||
.map(|u| InviteCodeUse {
|
||||
used_by: u.did.clone(),
|
||||
used_by_handle: Some(u.handle.clone()),
|
||||
used_at: u.used_at.to_rfc3339(),
|
||||
})
|
||||
.collect()
|
||||
|
||||
@@ -24,6 +24,7 @@ pub mod validation;
|
||||
|
||||
use axum::{
|
||||
Router,
|
||||
extract::DefaultBodyLimit,
|
||||
http::Method,
|
||||
middleware,
|
||||
routing::{any, get, post},
|
||||
@@ -618,6 +619,7 @@ pub fn app(state: AppState) -> Router {
|
||||
post(api::delegation::create_delegated_account),
|
||||
)
|
||||
.route("/xrpc/{*method}", any(api::proxy::proxy_handler))
|
||||
.layer(DefaultBodyLimit::max(util::get_max_blob_size()))
|
||||
.layer(middleware::from_fn(metrics::metrics_middleware))
|
||||
.layer(
|
||||
CorsLayer::new()
|
||||
|
||||
+13
@@ -1,9 +1,22 @@
|
||||
use axum::http::HeaderMap;
|
||||
use rand::Rng;
|
||||
use sqlx::PgPool;
|
||||
use std::sync::OnceLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
const BASE32_ALPHABET: &str = "abcdefghijklmnopqrstuvwxyz234567";
|
||||
const DEFAULT_MAX_BLOB_SIZE: usize = 10 * 1024 * 1024 * 1024;
|
||||
|
||||
static MAX_BLOB_SIZE: OnceLock<usize> = OnceLock::new();
|
||||
|
||||
pub fn get_max_blob_size() -> usize {
|
||||
*MAX_BLOB_SIZE.get_or_init(|| {
|
||||
std::env::var("MAX_BLOB_SIZE")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(DEFAULT_MAX_BLOB_SIZE)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn generate_token_code() -> String {
|
||||
generate_token_code_parts(2, 5)
|
||||
|
||||
Reference in New Issue
Block a user