Minimal subsonic functionality

This commit is contained in:
Connor Johnstone
2026-03-20 20:04:35 -04:00
parent abe321a317
commit 621355e352
19 changed files with 2107 additions and 22 deletions

View File

@@ -20,7 +20,14 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
.route(web::get().to(list_users))
.route(web::post().to(create_user)),
)
.service(web::resource("/auth/users/{id}").route(web::delete().to(delete_user)));
.service(web::resource("/auth/users/{id}").route(web::delete().to(delete_user)))
.service(
web::resource("/auth/subsonic-password").route(web::put().to(set_subsonic_password)),
)
.service(
web::resource("/auth/subsonic-password-status")
.route(web::get().to(subsonic_password_status)),
);
}
#[derive(Deserialize)]
@@ -41,6 +48,11 @@ struct CreateUserRequest {
password: String,
}
#[derive(Deserialize)]
struct SubsonicPasswordRequest {
password: String,
}
/// Check if initial setup is required (no users in database).
async fn setup_required(state: web::Data<AppState>) -> Result<HttpResponse, ApiError> {
let count = queries::users::count(state.db.conn()).await?;
@@ -205,3 +217,34 @@ async fn delete_user(
tracing::info!(user_id = user_id, "user deleted by admin");
Ok(HttpResponse::NoContent().finish())
}
/// Set the Subsonic password for the current user.
async fn set_subsonic_password(
state: web::Data<AppState>,
session: Session,
body: web::Json<SubsonicPasswordRequest>,
) -> Result<HttpResponse, ApiError> {
let (user_id, _, _) = auth::require_auth(&session)?;
if body.password.len() < 4 {
return Err(ApiError::BadRequest(
"password must be at least 4 characters".into(),
));
}
queries::users::set_subsonic_password(state.db.conn(), user_id, &body.password).await?;
tracing::info!(user_id = user_id, "subsonic password set");
Ok(HttpResponse::Ok().json(serde_json::json!({ "status": "ok" })))
}
/// Check whether the current user has a Subsonic password set.
async fn subsonic_password_status(
state: web::Data<AppState>,
session: Session,
) -> Result<HttpResponse, ApiError> {
let (user_id, _, _) = auth::require_auth(&session)?;
let user = queries::users::get_by_id(state.db.conn(), user_id).await?;
Ok(HttpResponse::Ok().json(serde_json::json!({
"set": user.subsonic_password.is_some(),
})))
}