Skip to content

Commit f497806

Browse files
Carlos Tocinophotovoltexkingosticks
authored
OAuth process made by a struct, allowing customization options. (#1462)
* get refresh token. Optional auth url browser opening * changelog * access token accepts custom message * docs updated * CustomParams renamed * OAuthToken can be cloned * builder pattern on token management * changelog * docs and format issues * split methods and finish documentation * new example and minor adjustments * typo * remove unnecessary dependency * requested changes * Update oauth/src/lib.rs Co-authored-by: Felix Prillwitz <[email protected]> * Update oauth/src/lib.rs Co-authored-by: Felix Prillwitz <[email protected]> * Update CHANGELOG.md Co-authored-by: Felix Prillwitz <[email protected]> * Update oauth/src/lib.rs Co-authored-by: Felix Prillwitz <[email protected]> * Update oauth/src/lib.rs Co-authored-by: Felix Prillwitz <[email protected]> * Update oauth/src/lib.rs Co-authored-by: Nick Steel <[email protected]> * Update oauth/src/lib.rs Co-authored-by: Nick Steel <[email protected]> * remove veil. Oauth flow fix * debug trait instead of veil * Update main.rs Co-authored-by: Nick Steel <[email protected]> --------- Co-authored-by: Felix Prillwitz <[email protected]> Co-authored-by: Nick Steel <[email protected]>
1 parent 581c8d6 commit f497806

8 files changed

Lines changed: 474 additions & 56 deletions

File tree

CHANGELOG.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
- [connect] Add `pause` parameter to `Spirc::disconnect` method (breaking)
2424
- [playback] Add `track` field to `PlayerEvent::RepeatChanged` (breaking)
2525
- [core] Add `request_with_options` and `request_with_protobuf_and_options` to `SpClient`
26+
- [oauth] Add `OAuthClient` and `OAuthClientBuilder` structs to achieve a more customizable login process
2627

2728
### Fixed
2829

@@ -39,6 +40,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3940
- [connect] Handle transfer of playback with empty "uri" field
4041
- [connect] Correctly apply playing/paused state when transferring playback
4142

43+
### Deprecated
44+
45+
- [oauth] `get_access_token()` function marked for deprecation
46+
4247
### Removed
4348

4449
- [core] Removed `get_canvases` from SpClient (breaking)
@@ -76,7 +81,7 @@ backend for Spotify Connect discovery.
7681
## [0.5.0] - 2024-10-15
7782

7883
This version is be a major departure from the architecture up until now. It
79-
focuses on implementing the "new Spotify API". This means moving large parts
84+
focuses on implementing the "new Spotify API". This means moving large parts
8085
of the Spotify protocol from Mercury to HTTP. A lot of this was reverse
8186
engineered before by @devgianlu of librespot-java. It was long overdue that we
8287
started implementing it too, not in the least because new features like the
@@ -219,14 +224,17 @@ to offer. But, unless anything big comes up, it is also intended as the last
219224
release to be based on the old API. Happy listening.
220225

221226
### Changed
227+
222228
- [playback] `pipe`: Better error handling
223229
- [playback] `subprocess`: Better error handling
224230

225231
### Added
232+
226233
- [core] `apresolve`: Blacklist ap-gew4 and ap-gue1 access points that cause channel errors
227234
- [playback] `pipe`: Implement stop
228235

229236
### Fixed
237+
230238
- [main] fix `--opt=value` line argument logging
231239
- [playback] `alsamixer`: make `--volume-ctrl fixed` work as expected when combined with `--mixer alsa`
232240

@@ -235,9 +243,11 @@ release to be based on the old API. Happy listening.
235243
This release fixes dependency issues when installing from crates.
236244

237245
### Changed
246+
238247
- [chore] The MSRV is now 1.56
239248

240249
### Fixed
250+
241251
- [playback] Fixed dependency issues when installing from crate
242252

243253
## [0.4.0] - 2022-05-21
@@ -253,6 +263,7 @@ Targeting that major effort for a v0.5 release sometime, we intend to maintain
253263
v0.4.x as a stable branch until then.
254264

255265
### Changed
266+
256267
- [chore] The MSRV is now 1.53
257268
- [contrib] Hardened security of the `systemd` service units
258269
- [core] `Session`: `connect()` now returns the long-term credentials
@@ -265,6 +276,7 @@ v0.4.x as a stable branch until then.
265276
- [playback] `Sink`: `write()` now receives ownership of the packet (breaking)
266277

267278
### Added
279+
268280
- [main] Enforce reasonable ranges for option values (breaking)
269281
- [main] Add the ability to parse environment variables
270282
- [main] Log now emits warning when trying to use options that would otherwise have no effect
@@ -277,6 +289,7 @@ v0.4.x as a stable branch until then.
277289
- [playback] `pulseaudio`: set values to: `PULSE_PROP_application.version`, `PULSE_PROP_application.process.binary`, `PULSE_PROP_stream.description`, `PULSE_PROP_media.software` and `PULSE_PROP_media.role` environment variables (user set env var values take precedence) (breaking)
278290

279291
### Fixed
292+
280293
- [connect] Don't panic when activating shuffle without previous interaction
281294
- [core] Removed unsafe code (breaking)
282295
- [main] Fix crash when built with Avahi support but Avahi is locally unavailable
@@ -287,20 +300,24 @@ v0.4.x as a stable branch until then.
287300
- [playback] `alsa`: make `--volume-range` overrides apply to Alsa softvol controls
288301

289302
### Removed
303+
290304
- [playback] `alsamixer`: previously deprecated options `mixer-card`, `mixer-name` and `mixer-index` have been removed
291305

292306
## [0.3.1] - 2021-10-24
293307

294308
### Changed
309+
295310
- Include build profile in the displayed version information
296311
- [playback] Improve dithering CPU usage by about 33%
297312

298313
### Fixed
314+
299315
- [connect] Partly fix behavior after last track of an album/playlist
300316

301317
## [0.3.0] - 2021-10-13
302318

303319
### Added
320+
304321
- [discovery] The crate `librespot-discovery` for discovery in LAN was created. Its functionality was previously part of `librespot-connect`.
305322
- [playback] Add support for dithering with `--dither` for lower requantization error (breaking)
306323
- [playback] Add `--volume-range` option to set dB range and control `log` and `cubic` volume control curves
@@ -309,6 +326,7 @@ v0.4.x as a stable branch until then.
309326
- [playback] Add `--normalisation-gain-type auto` that switches between album and track automatically
310327

311328
### Changed
329+
312330
- [audio, playback] Moved `VorbisDecoder`, `VorbisError`, `AudioPacket`, `PassthroughDecoder`, `PassthroughError`, `DecoderError`, `AudioDecoder` and the `convert` module from `librespot-audio` to `librespot-playback`. The underlying crates `vorbis`, `librespot-tremor`, `lewton` and `ogg` should be used directly. (breaking)
313331
- [audio, playback] Use `Duration` for time constants and functions (breaking)
314332
- [connect, playback] Moved volume controls from `librespot-connect` to `librespot-playback` crate
@@ -325,17 +343,20 @@ v0.4.x as a stable branch until then.
325343
- [playback] `player`: default normalisation type is now `auto`
326344

327345
### Deprecated
346+
328347
- [connect] The `discovery` module was deprecated in favor of the `librespot-discovery` crate
329348
- [playback] `alsamixer`: renamed `mixer-card` to `alsa-mixer-device`
330349
- [playback] `alsamixer`: renamed `mixer-name` to `alsa-mixer-control`
331350
- [playback] `alsamixer`: renamed `mixer-index` to `alsa-mixer-index`
332351

333352
### Removed
353+
334354
- [connect] Removed no-op mixer started/stopped logic (breaking)
335355
- [playback] Removed `with-vorbis` and `with-tremor` features
336356
- [playback] `alsamixer`: removed `--mixer-linear-volume` option, now that `--volume-ctrl {linear|log}` work as expected on Alsa
337357

338358
### Fixed
359+
339360
- [connect] Fix step size on volume up/down events
340361
- [connect] Fix looping back to the first track after the last track of an album or playlist
341362
- [playback] Incorrect `PlayerConfig::default().normalisation_threshold` caused distortion when using dynamic volume normalisation downstream

Cargo.lock

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

oauth/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ edition = "2021"
1111
[dependencies]
1212
log = "0.4"
1313
oauth2 = "4.4"
14+
open = "5.3"
1415
thiserror = "2.0"
1516
url = "2.2"
1617

1718
[dev-dependencies]
1819
env_logger = { version = "0.11.2", default-features = false, features = ["color", "humantime", "auto-color"] }
20+
tokio = { version = "1.43.0", features = ["rt-multi-thread", "macros"] }

oauth/examples/oauth.rs

Lines changed: 0 additions & 32 deletions
This file was deleted.

oauth/examples/oauth_async.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use std::env;
2+
3+
use librespot_oauth::OAuthClientBuilder;
4+
5+
const SPOTIFY_CLIENT_ID: &str = "65b708073fc0480ea92a077233ca87bd";
6+
const SPOTIFY_REDIRECT_URI: &str = "http://127.0.0.1:8898/login";
7+
8+
const RESPONSE: &str = r#"
9+
<!doctype html>
10+
<html>
11+
<body>
12+
<h1>Return to your app!</h1>
13+
</body>
14+
</html>
15+
"#;
16+
17+
#[tokio::main]
18+
async fn main() {
19+
let mut builder = env_logger::Builder::new();
20+
builder.parse_filters("librespot=trace");
21+
builder.init();
22+
23+
let args: Vec<_> = env::args().collect();
24+
let (client_id, redirect_uri, scopes) = if args.len() == 4 {
25+
// You can use your own client ID, along with it's associated redirect URI.
26+
(
27+
args[1].as_str(),
28+
args[2].as_str(),
29+
args[3].split(',').collect::<Vec<&str>>(),
30+
)
31+
} else if args.len() == 1 {
32+
(SPOTIFY_CLIENT_ID, SPOTIFY_REDIRECT_URI, vec!["streaming"])
33+
} else {
34+
eprintln!("Usage: {} [CLIENT_ID REDIRECT_URI SCOPES]", args[0]);
35+
return;
36+
};
37+
38+
let client = match OAuthClientBuilder::new(client_id, redirect_uri, scopes)
39+
.open_in_browser()
40+
.with_custom_message(RESPONSE)
41+
.build()
42+
{
43+
Ok(client) => client,
44+
Err(err) => {
45+
eprintln!("Unable to build an OAuth client: {}", err);
46+
return;
47+
}
48+
};
49+
50+
let refresh_token = match client.get_access_token_async().await {
51+
Ok(token) => {
52+
println!("OAuth Token: {token:#?}");
53+
token.refresh_token
54+
}
55+
Err(err) => {
56+
println!("Unable to get OAuth Token: {err}");
57+
return;
58+
}
59+
};
60+
61+
match client.refresh_token_async(&refresh_token).await {
62+
Ok(token) => println!("New refreshed OAuth Token: {token:#?}"),
63+
Err(err) => println!("Unable to get refreshed OAuth Token: {err}"),
64+
}
65+
}

oauth/examples/oauth_sync.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use std::env;
2+
3+
use librespot_oauth::OAuthClientBuilder;
4+
5+
const SPOTIFY_CLIENT_ID: &str = "65b708073fc0480ea92a077233ca87bd";
6+
const SPOTIFY_REDIRECT_URI: &str = "http://127.0.0.1:8898/login";
7+
8+
const RESPONSE: &str = r#"
9+
<!doctype html>
10+
<html>
11+
<body>
12+
<h1>Return to your app!</h1>
13+
</body>
14+
</html>
15+
"#;
16+
17+
fn main() {
18+
let mut builder = env_logger::Builder::new();
19+
builder.parse_filters("librespot=trace");
20+
builder.init();
21+
22+
let args: Vec<_> = env::args().collect();
23+
let (client_id, redirect_uri, scopes) = if args.len() == 4 {
24+
// You can use your own client ID, along with it's associated redirect URI.
25+
(
26+
args[1].as_str(),
27+
args[2].as_str(),
28+
args[3].split(',').collect::<Vec<&str>>(),
29+
)
30+
} else if args.len() == 1 {
31+
(SPOTIFY_CLIENT_ID, SPOTIFY_REDIRECT_URI, vec!["streaming"])
32+
} else {
33+
eprintln!("Usage: {} [CLIENT_ID REDIRECT_URI SCOPES]", args[0]);
34+
return;
35+
};
36+
37+
let client = match OAuthClientBuilder::new(client_id, redirect_uri, scopes)
38+
.open_in_browser()
39+
.with_custom_message(RESPONSE)
40+
.build()
41+
{
42+
Ok(client) => client,
43+
Err(err) => {
44+
eprintln!("Unable to build an OAuth client: {}", err);
45+
return;
46+
}
47+
};
48+
49+
let refresh_token = match client.get_access_token() {
50+
Ok(token) => {
51+
println!("OAuth Token: {token:#?}");
52+
token.refresh_token
53+
}
54+
Err(err) => {
55+
println!("Unable to get OAuth Token: {err}");
56+
return;
57+
}
58+
};
59+
60+
match client.refresh_token(&refresh_token) {
61+
Ok(token) => println!("New refreshed OAuth Token: {token:#?}"),
62+
Err(err) => println!("Unable to get refreshed OAuth Token: {err}"),
63+
}
64+
}

0 commit comments

Comments
 (0)