Minimal subsonic functionality

This commit is contained in:
Connor Johnstone
2026-03-20 20:04:35 -04:00
parent 4fda9071c7
commit 1f983bbecf
4 changed files with 53 additions and 0 deletions

View File

@@ -19,6 +19,9 @@ pub struct Model {
pub username: String,
#[serde(skip_serializing)]
pub password_hash: String,
#[serde(skip_serializing)]
#[sea_orm(nullable)]
pub subsonic_password: Option<String>,
pub role: UserRole,
pub created_at: chrono::NaiveDateTime,
pub updated_at: chrono::NaiveDateTime,

View File

@@ -0,0 +1,35 @@
use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.alter_table(
Table::alter()
.table(Users::Table)
.add_column(ColumnDef::new(Users::SubsonicPassword).text())
.to_owned(),
)
.await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.alter_table(
Table::alter()
.table(Users::Table)
.drop_column(Users::SubsonicPassword)
.to_owned(),
)
.await
}
}
#[derive(DeriveIden)]
enum Users {
Table,
SubsonicPassword,
}

View File

@@ -13,6 +13,7 @@ mod m20260319_000011_create_users;
mod m20260319_000012_add_user_id_to_wanted_items;
mod m20260320_000013_add_artist_monitoring;
mod m20260320_000014_create_playlists;
mod m20260320_000015_add_subsonic_password;
pub struct Migrator;
@@ -33,6 +34,7 @@ impl MigratorTrait for Migrator {
Box::new(m20260319_000012_add_user_id_to_wanted_items::Migration),
Box::new(m20260320_000013_add_artist_monitoring::Migration),
Box::new(m20260320_000014_create_playlists::Migration),
Box::new(m20260320_000015_add_subsonic_password::Migration),
]
}
}

View File

@@ -52,6 +52,19 @@ pub async fn count(db: &DatabaseConnection) -> DbResult<u64> {
Ok(Users::find().count(db).await?)
}
/// Set the Subsonic password for a user. Stored as plaintext per the Subsonic protocol.
pub async fn set_subsonic_password(
db: &DatabaseConnection,
user_id: i32,
password: &str,
) -> DbResult<User> {
let existing = get_by_id(db, user_id).await?;
let mut active: ActiveModel = existing.into();
active.subsonic_password = Set(Some(password.to_string()));
active.updated_at = Set(Utc::now().naive_utc());
Ok(active.update(db).await?)
}
/// Assign all orphaned wanted items (user_id IS NULL) to the given user.
pub async fn adopt_orphaned_wanted_items(db: &DatabaseConnection, user_id: i32) -> DbResult<u64> {
use crate::entities::wanted_item;