Skip to content

Commit

Permalink
fix: Libre.fm auth not working
Browse files Browse the repository at this point in the history
  • Loading branch information
Losses committed Dec 18, 2024
1 parent ed73d1e commit 40bf5b5
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 20 deletions.
26 changes: 12 additions & 14 deletions scrobbling/examples/scrobble_random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,32 @@ async fn main() -> Result<()> {
.index(1),
)
.arg(
Arg::new("api_key")
.help("API Key for the service")
Arg::new("username")
.help("Username for the service")
.required(true)
.index(2),
)
.arg(
Arg::new("api_secret")
.help("API Secret for Last.fm (ignored for Libre.fm)")
.required(false)
Arg::new("password")
.help("Password for the service")
.required(true)
.index(3),
)
.arg(
Arg::new("username")
.help("Username for the service")
.required(true)
.index(4),
Arg::new("api_key")
.help("API Key for the service")
.long("api_key"),
)
.arg(
Arg::new("password")
.help("Password for the service")
.required(true)
.index(5),
Arg::new("api_secret")
.help("API Secret for Last.fm (ignored for Libre.fm)")
.long("api_secret"),
)
.get_matches();

let binding = "".to_string();
let service = matches.get_one::<String>("service").unwrap();
let api_key = matches.get_one::<String>("api_key").unwrap();
let api_key = matches.get_one::<String>("api_key").unwrap_or(&binding);
let api_secret = matches.get_one::<String>("api_secret").unwrap_or(&binding);
let username = matches.get_one::<String>("username").unwrap();
let password = matches.get_one::<String>("password").unwrap();
Expand Down
18 changes: 16 additions & 2 deletions scrobbling/src/last_fm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,22 @@ impl ScrobblingClient for LastFmClient {

if response.status().is_success() {
let auth_response: AuthResponse = response.json().await?;
self.session_key = Some(auth_response.session.key);
Ok(())

if auth_response.error.is_some() {
bail!(
"Authentication failed: {}",
auth_response
.message
.unwrap_or_else(|| "Unknown error".to_string())
);
}

if let Some(session) = auth_response.session {
self.session_key = Some(session.key);
Ok(())
} else {
bail!("Authentication failed: No session key returned");
}
} else {
bail!("Authentication failed")
}
Expand Down
4 changes: 3 additions & 1 deletion scrobbling/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize)]
struct AuthResponse {
session: SessionInfo,
session: Option<SessionInfo>,
error: Option<i32>,
message: Option<String>,
}

#[derive(Debug, Deserialize)]
Expand Down
31 changes: 28 additions & 3 deletions scrobbling/src/libre_fm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,20 @@ impl LibreFmClient {
#[async_trait]
impl ScrobblingClient for LibreFmClient {
async fn authenticate(&mut self, username: &str, password: &str) -> Result<()> {
// Compute MD5 of the password
let password_hash = format!("{:x}", md5::compute(password));

// Compute the authentication token
let authtoken = format!(
"{:x}",
md5::compute(format!("{}{}", username.to_lowercase(), password_hash))
);

let mut params = HashMap::new();
params.insert("method".to_string(), "auth.getMobileSession".to_string());
params.insert("username".to_string(), username.to_string());
params.insert("password".to_string(), password.to_string());
params.insert("authtoken".to_string(), authtoken);
params.insert("api_key".to_string(), "0".repeat(32));

let response = self
Expand All @@ -43,10 +53,25 @@ impl ScrobblingClient for LibreFmClient {

if response.status().is_success() {
let auth_response: AuthResponse = response.json().await?;
self.session_key = Some(auth_response.session.key);
Ok(())

if auth_response.error.is_some() {
bail!(
"Authentication failed: {}",
auth_response
.message
.unwrap_or_else(|| "Unknown error".to_string())
);
}

if let Some(session) = auth_response.session {
self.session_key = Some(session.key);
Ok(())
} else {
bail!("Authentication failed: No session key returned");
}
} else {
bail!("Authentication failed")
let error_text = response.text().await?;
bail!("Authentication failed: {}", error_text)
}
}

Expand Down

0 comments on commit 40bf5b5

Please sign in to comment.