mirror of
https://github.com/librespot-org/librespot.git
synced 2024-11-08 16:45:43 +00:00
fix: map authentication errors to a custom error type
This commit is contained in:
parent
06f5aa9c90
commit
71e9295ee8
4 changed files with 51 additions and 14 deletions
|
@ -13,6 +13,7 @@ use std::ops::FnOnce;
|
|||
use std::path::Path;
|
||||
|
||||
use crate::protocol::authentication::AuthenticationType;
|
||||
use crate::protocol::keyexchange::{APLoginFailed, ErrorCode};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Credentials {
|
||||
|
@ -191,3 +192,37 @@ pub fn get_credentials<F: FnOnce(&String) -> String>(
|
|||
(None, _, None) => None,
|
||||
}
|
||||
}
|
||||
|
||||
error_chain! {
|
||||
types {
|
||||
AuthenticationError, AuthenticationErrorKind, AuthenticationResultExt, AuthenticationResult;
|
||||
}
|
||||
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
}
|
||||
|
||||
errors {
|
||||
BadCredentials {
|
||||
description("Bad credentials")
|
||||
display("Authentication failed with error: Bad credentials")
|
||||
}
|
||||
PremiumAccountRequired {
|
||||
description("Premium account required")
|
||||
display("Authentication failed with error: Premium account required")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<APLoginFailed> for AuthenticationError {
|
||||
fn from(login_failure: APLoginFailed) -> Self {
|
||||
let error_code = login_failure.get_error_code();
|
||||
match error_code {
|
||||
ErrorCode::BadCredentials => Self::from_kind(AuthenticationErrorKind::BadCredentials),
|
||||
ErrorCode::PremiumAccountRequired => {
|
||||
Self::from_kind(AuthenticationErrorKind::PremiumAccountRequired)
|
||||
}
|
||||
_ => format!("Authentication failed with error: {:?}", error_code).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use tokio_core::net::TcpStream;
|
|||
use tokio_core::reactor::Handle;
|
||||
use url::Url;
|
||||
|
||||
use crate::authentication::Credentials;
|
||||
use crate::authentication::{AuthenticationError, Credentials};
|
||||
use crate::version;
|
||||
|
||||
use crate::proxytunnel;
|
||||
|
@ -66,7 +66,7 @@ pub fn authenticate(
|
|||
transport: Transport,
|
||||
credentials: Credentials,
|
||||
device_id: String,
|
||||
) -> Box<dyn Future<Item = (Transport, Credentials), Error = io::Error>> {
|
||||
) -> Box<dyn Future<Item = (Transport, Credentials), Error = AuthenticationError>> {
|
||||
use crate::protocol::authentication::{APWelcome, ClientResponseEncrypted, CpuFamily, Os};
|
||||
use crate::protocol::keyexchange::APLoginFailed;
|
||||
|
||||
|
@ -101,6 +101,7 @@ pub fn authenticate(
|
|||
transport
|
||||
.send((cmd, data))
|
||||
.and_then(|transport| transport.into_future().map_err(|(err, _stream)| err))
|
||||
.map_err(|io_err| io_err.into())
|
||||
.and_then(|(packet, transport)| match packet {
|
||||
Some((0xac, data)) => {
|
||||
let welcome_data: APWelcome =
|
||||
|
@ -118,10 +119,7 @@ pub fn authenticate(
|
|||
Some((0xad, data)) => {
|
||||
let error_data: APLoginFailed =
|
||||
protobuf::parse_from_bytes(data.as_ref()).unwrap();
|
||||
panic!(
|
||||
"Authentication failed with reason: {:?}",
|
||||
error_data.get_error_code()
|
||||
)
|
||||
Err(error_data.into())
|
||||
}
|
||||
|
||||
Some((cmd, _)) => panic!("Unexpected packet {:?}", cmd),
|
||||
|
|
|
@ -19,6 +19,8 @@ use crate::config::SessionConfig;
|
|||
use crate::connection;
|
||||
use crate::mercury::MercuryManager;
|
||||
|
||||
pub use crate::authentication::{AuthenticationError, AuthenticationErrorKind};
|
||||
|
||||
struct SessionData {
|
||||
country: String,
|
||||
time_delta: i64,
|
||||
|
@ -53,16 +55,18 @@ impl Session {
|
|||
credentials: Credentials,
|
||||
cache: Option<Cache>,
|
||||
handle: Handle,
|
||||
) -> Box<dyn Future<Item = Session, Error = io::Error>> {
|
||||
) -> Box<dyn Future<Item = Session, Error = AuthenticationError>> {
|
||||
let access_point =
|
||||
apresolve_or_fallback::<io::Error>(&handle, &config.proxy, &config.ap_port);
|
||||
|
||||
let handle_ = handle.clone();
|
||||
let proxy = config.proxy.clone();
|
||||
let connection = access_point.and_then(move |addr| {
|
||||
let connection = access_point
|
||||
.and_then(move |addr| {
|
||||
info!("Connecting to AP \"{}\"", addr);
|
||||
connection::connect(addr, &handle_, &proxy)
|
||||
});
|
||||
})
|
||||
.map_err(|io_err| io_err.into());
|
||||
|
||||
let device_id = config.device_id.clone();
|
||||
let authentication = connection.and_then(move |connection| {
|
||||
|
|
|
@ -3,7 +3,7 @@ use futures::{Async, Future, Poll, Stream};
|
|||
use log::{error, info, trace, warn};
|
||||
use sha1::{Digest, Sha1};
|
||||
use std::env;
|
||||
use std::io::{self, stderr, Write};
|
||||
use std::io::{stderr, Write};
|
||||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
use std::process::exit;
|
||||
|
@ -16,7 +16,7 @@ use url::Url;
|
|||
use librespot::core::authentication::{get_credentials, Credentials};
|
||||
use librespot::core::cache::Cache;
|
||||
use librespot::core::config::{ConnectConfig, DeviceType, SessionConfig, VolumeCtrl};
|
||||
use librespot::core::session::Session;
|
||||
use librespot::core::session::{AuthenticationError, Session};
|
||||
use librespot::core::version;
|
||||
|
||||
use librespot::connect::discovery::{discovery, DiscoveryStream};
|
||||
|
@ -406,7 +406,7 @@ struct Main {
|
|||
|
||||
spirc: Option<Spirc>,
|
||||
spirc_task: Option<SpircTask>,
|
||||
connect: Box<dyn Future<Item = Session, Error = io::Error>>,
|
||||
connect: Box<dyn Future<Item = Session, Error = AuthenticationError>>,
|
||||
|
||||
shutdown: bool,
|
||||
last_credentials: Option<Credentials>,
|
||||
|
|
Loading…
Reference in a new issue