Initial commit — ferrosonic terminal Subsonic client
Terminal-based Subsonic music client in Rust featuring bit-perfect audio playback via PipeWire sample rate switching, gapless playback, MPRIS2 desktop integration, cava audio visualizer with theme-matched gradients, 13 built-in color themes with custom TOML theme support, mouse controls, artist/album browser, playlist support, and play queue management. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
61
src/subsonic/auth.rs
Normal file
61
src/subsonic/auth.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
//! Subsonic authentication helpers
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
/// Generate authentication parameters for Subsonic API requests
|
||||
///
|
||||
/// Subsonic uses token-based authentication:
|
||||
/// - salt: random string
|
||||
/// - token: md5(password + salt)
|
||||
pub fn generate_auth_params(password: &str) -> (String, String) {
|
||||
let salt = generate_salt();
|
||||
let token = generate_token(password, &salt);
|
||||
(salt, token)
|
||||
}
|
||||
|
||||
/// Generate a random salt string
|
||||
fn generate_salt() -> String {
|
||||
let mut rng = rand::thread_rng();
|
||||
(0..16)
|
||||
.map(|_| {
|
||||
let idx = rng.gen_range(0..36);
|
||||
if idx < 10 {
|
||||
(b'0' + idx) as char
|
||||
} else {
|
||||
(b'a' + idx - 10) as char
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Generate authentication token: md5(password + salt)
|
||||
fn generate_token(password: &str, salt: &str) -> String {
|
||||
let input = format!("{}{}", password, salt);
|
||||
let digest = md5::compute(input.as_bytes());
|
||||
format!("{:x}", digest)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_generate_token() {
|
||||
// Test with known values
|
||||
let token = generate_token("sesame", "c19b2d");
|
||||
assert_eq!(token, "26719a1196d2a940705a59634eb18eab");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_salt_length() {
|
||||
let salt = generate_salt();
|
||||
assert_eq!(salt.len(), 16);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_auth_params() {
|
||||
let (salt, token) = generate_auth_params("password");
|
||||
assert_eq!(salt.len(), 16);
|
||||
assert_eq!(token.len(), 32); // MD5 hex is 32 chars
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user