mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Retrieve client token (not working)
This commit is contained in:
parent
0630586cd6
commit
1528292583
4 changed files with 74 additions and 9 deletions
|
@ -5,7 +5,7 @@ use futures_util::future::IntoStream;
|
||||||
use http::header::HeaderValue;
|
use http::header::HeaderValue;
|
||||||
use hyper::{
|
use hyper::{
|
||||||
client::ResponseFuture,
|
client::ResponseFuture,
|
||||||
header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE, RANGE},
|
header::{ACCEPT, AUTHORIZATION, CONTENT_ENCODING, CONTENT_TYPE, RANGE},
|
||||||
Body, HeaderMap, Method, Request,
|
Body, HeaderMap, Method, Request,
|
||||||
};
|
};
|
||||||
use protobuf::Message;
|
use protobuf::Message;
|
||||||
|
@ -17,16 +17,19 @@ use crate::{
|
||||||
cdn_url::CdnUrl,
|
cdn_url::CdnUrl,
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
protocol::{
|
protocol::{
|
||||||
canvaz::EntityCanvazRequest, connect::PutStateRequest,
|
canvaz::EntityCanvazRequest,
|
||||||
|
clienttoken_http::{ClientTokenRequest, ClientTokenRequestType, ClientTokenResponse},
|
||||||
|
connect::PutStateRequest,
|
||||||
extended_metadata::BatchedEntityRequest,
|
extended_metadata::BatchedEntityRequest,
|
||||||
},
|
},
|
||||||
Error, FileId, SpotifyId,
|
version, Error, FileId, SpotifyId,
|
||||||
};
|
};
|
||||||
|
|
||||||
component! {
|
component! {
|
||||||
SpClient : SpClientInner {
|
SpClient : SpClientInner {
|
||||||
accesspoint: Option<SocketAddress> = None,
|
accesspoint: Option<SocketAddress> = None,
|
||||||
strategy: RequestStrategy = RequestStrategy::default(),
|
strategy: RequestStrategy = RequestStrategy::default(),
|
||||||
|
client_token: String = String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +91,51 @@ impl SpClient {
|
||||||
Ok(format!("https://{}:{}", ap.0, ap.1))
|
Ok(format!("https://{}:{}", ap.0, ap.1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn client_token(&self) -> Result<String, Error> {
|
||||||
|
// TODO: implement expiry
|
||||||
|
let client_token = self.lock(|inner| inner.client_token.clone());
|
||||||
|
if !client_token.is_empty() {
|
||||||
|
return Ok(client_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut message = ClientTokenRequest::new();
|
||||||
|
message.set_request_type(ClientTokenRequestType::REQUEST_CLIENT_DATA_REQUEST);
|
||||||
|
|
||||||
|
let client_data = message.mut_client_data();
|
||||||
|
client_data.set_client_id(self.session().client_id());
|
||||||
|
client_data.set_client_version(version::SEMVER.to_string());
|
||||||
|
|
||||||
|
let connectivity_data = client_data.mut_connectivity_sdk_data();
|
||||||
|
connectivity_data.set_device_id(self.session().device_id().to_string());
|
||||||
|
|
||||||
|
let platform_data = connectivity_data.mut_platform_specific_data();
|
||||||
|
let windows_data = platform_data.mut_windows();
|
||||||
|
windows_data.set_os_version(10);
|
||||||
|
windows_data.set_os_build(21370);
|
||||||
|
windows_data.set_unknown_value_4(2);
|
||||||
|
windows_data.set_unknown_value_6(9);
|
||||||
|
windows_data.set_unknown_value_7(332);
|
||||||
|
windows_data.set_unknown_value_8(34404);
|
||||||
|
windows_data.set_unknown_value_10(true);
|
||||||
|
|
||||||
|
let body = protobuf::text_format::print_to_string(&message);
|
||||||
|
|
||||||
|
let request = Request::builder()
|
||||||
|
.method(&Method::POST)
|
||||||
|
.uri("https://clienttoken.spotify.com/v1/clienttoken")
|
||||||
|
.header(ACCEPT, HeaderValue::from_static("application/x-protobuf"))
|
||||||
|
.header(CONTENT_ENCODING, HeaderValue::from_static(""))
|
||||||
|
.body(Body::from(body))?;
|
||||||
|
|
||||||
|
let response = self.session().http_client().request_body(request).await?;
|
||||||
|
let response = ClientTokenResponse::parse_from_bytes(&response)?;
|
||||||
|
|
||||||
|
let client_token = response.get_granted_token().get_token().to_owned();
|
||||||
|
self.lock(|inner| inner.client_token = client_token.clone());
|
||||||
|
|
||||||
|
Ok(client_token)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn request_with_protobuf(
|
pub async fn request_with_protobuf(
|
||||||
&self,
|
&self,
|
||||||
method: &Method,
|
method: &Method,
|
||||||
|
@ -100,7 +148,7 @@ impl SpClient {
|
||||||
let mut headers = headers.unwrap_or_else(HeaderMap::new);
|
let mut headers = headers.unwrap_or_else(HeaderMap::new);
|
||||||
headers.insert(
|
headers.insert(
|
||||||
CONTENT_TYPE,
|
CONTENT_TYPE,
|
||||||
HeaderValue::from_static("application/protobuf"),
|
HeaderValue::from_static("application/x-protobuf"),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.request(method, endpoint, Some(headers), Some(body))
|
self.request(method, endpoint, Some(headers), Some(body))
|
||||||
|
@ -132,6 +180,9 @@ impl SpClient {
|
||||||
|
|
||||||
let body = body.unwrap_or_else(String::new);
|
let body = body.unwrap_or_else(String::new);
|
||||||
|
|
||||||
|
let client_token = self.client_token().await;
|
||||||
|
trace!("CLIENT TOKEN: {:?}", client_token);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
tries += 1;
|
tries += 1;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ fn compile() {
|
||||||
|
|
||||||
let files = &[
|
let files = &[
|
||||||
proto_dir.join("connect.proto"),
|
proto_dir.join("connect.proto"),
|
||||||
|
proto_dir.join("connectivity.proto"),
|
||||||
proto_dir.join("devices.proto"),
|
proto_dir.join("devices.proto"),
|
||||||
proto_dir.join("entity_extension_data.proto"),
|
proto_dir.join("entity_extension_data.proto"),
|
||||||
proto_dir.join("extended_metadata.proto"),
|
proto_dir.join("extended_metadata.proto"),
|
||||||
|
@ -26,6 +27,7 @@ fn compile() {
|
||||||
proto_dir.join("playlist_annotate3.proto"),
|
proto_dir.join("playlist_annotate3.proto"),
|
||||||
proto_dir.join("playlist_permission.proto"),
|
proto_dir.join("playlist_permission.proto"),
|
||||||
proto_dir.join("playlist4_external.proto"),
|
proto_dir.join("playlist4_external.proto"),
|
||||||
|
proto_dir.join("spotify/clienttoken/v0/clienttoken_http.proto"),
|
||||||
proto_dir.join("storage-resolve.proto"),
|
proto_dir.join("storage-resolve.proto"),
|
||||||
proto_dir.join("user_attributes.proto"),
|
proto_dir.join("user_attributes.proto"),
|
||||||
// TODO: remove these legacy protobufs when we are on the new API completely
|
// TODO: remove these legacy protobufs when we are on the new API completely
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// Extracted from: Spotify 1.1.33.569 (Windows)
|
|
||||||
|
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
package spotify.clienttoken.data.v0;
|
package spotify.clienttoken.data.v0;
|
||||||
|
@ -17,6 +15,7 @@ message PlatformSpecificData {
|
||||||
oneof data {
|
oneof data {
|
||||||
NativeAndroidData android = 1;
|
NativeAndroidData android = 1;
|
||||||
NativeIOSData ios = 2;
|
NativeIOSData ios = 2;
|
||||||
|
NativeWindowsData windows = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +35,16 @@ message NativeIOSData {
|
||||||
string simulator_model_identifier = 5;
|
string simulator_model_identifier = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message NativeWindowsData {
|
||||||
|
int32 os_version = 1;
|
||||||
|
int32 os_build = 3;
|
||||||
|
int32 unknown_value_4 = 4;
|
||||||
|
int32 unknown_value_6 = 6;
|
||||||
|
int32 unknown_value_7 = 7;
|
||||||
|
int32 unknown_value_8 = 8;
|
||||||
|
bool unknown_value_10 = 10;
|
||||||
|
}
|
||||||
|
|
||||||
message Screen {
|
message Screen {
|
||||||
int32 width = 1;
|
int32 width = 1;
|
||||||
int32 height = 2;
|
int32 height = 2;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// Extracted from: Spotify 1.1.33.569 (Windows)
|
|
||||||
|
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
package spotify.clienttoken.http.v0;
|
package spotify.clienttoken.http.v0;
|
||||||
|
@ -24,7 +22,7 @@ message ClientDataRequest {
|
||||||
string client_id = 2;
|
string client_id = 2;
|
||||||
|
|
||||||
oneof data {
|
oneof data {
|
||||||
data.v0.ConnectivitySdkData connectivity_sdk_data = 3;
|
spotify.clienttoken.data.v0.ConnectivitySdkData connectivity_sdk_data = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,10 +40,15 @@ message ClientTokenResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message TokenDomain {
|
||||||
|
string domain = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message GrantedTokenResponse {
|
message GrantedTokenResponse {
|
||||||
string token = 1;
|
string token = 1;
|
||||||
int32 expires_after_seconds = 2;
|
int32 expires_after_seconds = 2;
|
||||||
int32 refresh_after_seconds = 3;
|
int32 refresh_after_seconds = 3;
|
||||||
|
repeated TokenDomain domains = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ChallengesResponse {
|
message ChallengesResponse {
|
||||||
|
|
Loading…
Reference in a new issue