1
1
use log:: { debug, error, info, trace} ;
2
- use oauth2:: basic:: {
3
- BasicErrorResponse , BasicRevocationErrorResponse , BasicTokenIntrospectionResponse ,
4
- BasicTokenType ,
5
- } ;
6
2
use oauth2:: reqwest:: http_client;
7
3
use oauth2:: {
8
- AuthUrl , AuthorizationCode , Client , ClientId , CsrfToken , ExtraTokenFields , PkceCodeChallenge ,
9
- RedirectUrl , Scope , StandardRevocableToken , StandardTokenResponse , TokenResponse , TokenUrl ,
4
+ basic :: BasicClient , AuthUrl , AuthorizationCode , ClientId , CsrfToken , PkceCodeChallenge ,
5
+ RedirectUrl , Scope , TokenResponse , TokenUrl ,
10
6
} ;
11
- use serde:: { Deserialize , Serialize } ;
12
7
use std:: io;
13
8
use std:: {
14
9
io:: { BufRead , BufReader , Write } ,
@@ -18,33 +13,6 @@ use std::{
18
13
} ;
19
14
use url:: Url ;
20
15
21
- // Define extra fields to get the username too.
22
- // TODO: Maybe don't bother and use simpler BasicClient instead?
23
-
24
- #[ derive( Clone , Debug , Deserialize , PartialEq , Serialize ) ]
25
- pub struct SpotifyFields {
26
- #[ serde( rename = "username" ) ]
27
- #[ serde( skip_serializing_if = "Option::is_none" ) ]
28
- pub username : Option < String > ,
29
- }
30
- impl SpotifyFields {
31
- pub fn username ( & self ) -> Option < & String > {
32
- self . username . as_ref ( )
33
- }
34
- }
35
- impl ExtraTokenFields for SpotifyFields { }
36
-
37
- type SpotifyTokenResponse = StandardTokenResponse < SpotifyFields , BasicTokenType > ;
38
-
39
- type SpotifyClient = Client <
40
- BasicErrorResponse ,
41
- SpotifyTokenResponse ,
42
- BasicTokenType ,
43
- BasicTokenIntrospectionResponse ,
44
- StandardRevocableToken ,
45
- BasicRevocationErrorResponse ,
46
- > ;
47
-
48
16
fn get_authcode_stdin ( ) -> AuthorizationCode {
49
17
println ! ( "Provide code" ) ;
50
18
let mut buffer = String :: new ( ) ;
@@ -90,29 +58,25 @@ fn get_authcode_listener(socket_address: SocketAddr) -> AuthorizationCode {
90
58
code
91
59
}
92
60
93
- // TODO: Return a Result
61
+ // TODO: Return a Result?
94
62
// TODO: Pass in redirect_address instead since the redirect host depends on client ID?
95
- // TODO: Should also return username, for fun?
96
63
pub fn get_access_token ( client_id : & str , redirect_port : u16 ) -> String {
97
64
// Must use host 127.0.0.1 with Spotify Desktop client ID.
98
65
let redirect_address = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , redirect_port) ;
99
66
let redirect_uri = format ! ( "http://{redirect_address}/login" ) ;
100
67
101
- let client = SpotifyClient :: new (
68
+ let client = BasicClient :: new (
102
69
ClientId :: new ( client_id. to_string ( ) ) ,
103
70
None ,
104
- AuthUrl :: new ( "https://accounts.spotify.com/authorize" . to_string ( ) )
105
- . expect ( "Invalid authorization endpoint URL" ) ,
106
- Some (
107
- TokenUrl :: new ( "https://accounts.spotify.com/api/token" . to_string ( ) )
108
- . expect ( "Invalid token endpoint URL" ) ,
109
- ) ,
71
+ AuthUrl :: new ( "https://accounts.spotify.com/authorize" . to_string ( ) ) . unwrap ( ) ,
72
+ Some ( TokenUrl :: new ( "https://accounts.spotify.com/api/token" . to_string ( ) ) . unwrap ( ) ) ,
110
73
)
111
74
. set_redirect_uri ( RedirectUrl :: new ( redirect_uri) . expect ( "Invalid redirect URL" ) ) ;
112
75
113
76
let ( pkce_challenge, pkce_verifier) = PkceCodeChallenge :: new_random_sha256 ( ) ;
114
77
115
78
// Generate the full authorization URL.
79
+ // Some of these scopes are unavailable for custom client IDs. Which?
116
80
let scopes = vec ! [
117
81
"app-remote-control" ,
118
82
"playlist-modify" ,
@@ -169,15 +133,15 @@ pub fn get_access_token(client_id: &str, redirect_port: u16) -> String {
169
133
} ) ;
170
134
let token_response = rx. recv ( ) . unwrap ( ) ;
171
135
let token = match token_response {
172
- Ok ( tok) => tok,
136
+ Ok ( tok) => {
137
+ trace ! ( "Obtained new access token: {tok:?}" ) ;
138
+ tok
139
+ }
173
140
Err ( e) => {
174
141
error ! ( "Failed to exchange code for access token: {e:?}" ) ;
175
142
exit ( 1 ) ;
176
143
}
177
144
} ;
178
- let username = token. extra_fields ( ) . username ( ) . unwrap ( ) . to_string ( ) ;
179
- let access_token = token. access_token ( ) . secret ( ) . to_string ( ) ;
180
- trace ! ( "Obtained new access token for {username}: {token:?}" ) ;
181
145
182
- access_token
146
+ token . access_token ( ) . secret ( ) . to_string ( )
183
147
}
0 commit comments