Skip to content

Commit 2acb6aa

Browse files
Merge #95
95: more non-async compat with new feature flag `client` and `::from_response` methods and `*_request` methods r=Emilgardis a=Emilgardis Enables usage of the crate only as a parser + types The client specific functions are now enabled via the `client` feature. This enables more specific handling of the http requests and makes testing easier. Co-authored-by: Emil Gardström <emil.gardstrom@gmail.com>
2 parents 0a0ecc8 + f657e9b commit 2acb6aa

File tree

11 files changed

+591
-303
lines changed

11 files changed

+591
-303
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
uses: actions/cache@v1
3939
id: cache
4040
with:
41-
path: |
41+
path: |
4242
~/.cargo/registry/index
4343
~/.cargo/registry/cache
4444
~/.cargo/git
@@ -65,7 +65,6 @@ jobs:
6565
with:
6666
command: fmt
6767
args: --all -- --check
68-
6968
clippy:
7069
name: Clippy
7170
runs-on: ubuntu-latest
@@ -81,17 +80,22 @@ jobs:
8180
uses: actions/cache@v1
8281
id: cache
8382
with:
84-
path: |
83+
path: |
8584
~/.cargo/registry/index
8685
~/.cargo/registry/cache
8786
~/.cargo/git
8887
target
8988
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
89+
- name: Run clippy
90+
uses: actions-rs/cargo@v1
91+
with:
92+
command: clippy
93+
args: --locked
9094
- name: Run clippy --all-targets --all-features
9195
uses: actions-rs/cargo@v1
9296
with:
9397
command: clippy
94-
args: --locked --all-targets --all-features
98+
args: --locked --all-targets --all-features
9599
docs:
96100
name: Docs
97101
runs-on: ubuntu-latest
@@ -106,7 +110,7 @@ jobs:
106110
uses: actions/cache@v1
107111
id: cache
108112
with:
109-
path: |
113+
path: |
110114
~/.cargo/registry/index
111115
~/.cargo/registry/cache
112116
~/.cargo/git

CHANGELOG.md

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,33 @@
66

77
[Commits](https://github.com/twitch-rs/twitch_oauth2/compare/v0.8.0...Unreleased)
88

9+
### Breaking
10+
11+
- Added new feature flag `client` that enables client specific functions. Without this feature,
12+
`twitch_oauth2` will only provide non-async functions and
13+
provide library users functions that returns `http::Request`s and consume `http::Response`s.
14+
- `ValidatedToken::expires_in` is now an `Option`.
15+
916
## [v0.8.0] - 2022-08-27
1017

1118
[Commits](https://github.com/twitch-rs/twitch_oauth2/compare/v0.7.1...v0.8.0)
1219

1320
### Breaking
1421

15-
* Bumped `aliri_braid` to `0.2`, this change means that the `new` method on the types in `types` only take an owned string now
16-
* `AccessToken::new`, `ClientId::new`, `ClientSecret::new`, `CsrfToken::new` and `RefreshToken::new` now take a `String` instead of `impl Into<String>`
22+
- Bumped `aliri_braid` to `0.2`, this change means that the `new` method on the types in `types` only take an owned string now
23+
- `AccessToken::new`, `ClientId::new`, `ClientSecret::new`, `CsrfToken::new` and `RefreshToken::new` now take a `String` instead of `impl Into<String>`
1724

1825
## [v0.7.1] - 2022-08-27
1926

2027
[Commits](https://github.com/twitch-rs/twitch_oauth2/compare/v0.7.0...v0.7.1)
2128

2229
### Changed
2330

24-
* Organization moved to `twitch-rs`
31+
- Organization moved to `twitch-rs`
2532

2633
### Added
2734

28-
* Added scopes `channel:manage:raids`, `channel:manage:moderators`, `channel:manage:vips`, `channel:read:charity`,
35+
- Added scopes `channel:manage:raids`, `channel:manage:moderators`, `channel:manage:vips`, `channel:read:charity`,
2936
`channel:read:vips`, `moderator:manage:announcements`, `moderator:manage:chat_messages`, `user:manage:chat_color` and
3037
`user:manage:whispers`
3138

@@ -35,16 +42,16 @@
3542

3643
### Breaking changes
3744

38-
* switch to [`twitch_types`](https://crates.io/crates/twitch_types) for `UserId` and `Nickname`/`UserName`
39-
* bump MSRV to 1.60, also changes the feature names for clients to their simpler variant `surf` and `client`
45+
- switch to [`twitch_types`](https://crates.io/crates/twitch_types) for `UserId` and `Nickname`/`UserName`
46+
- bump MSRV to 1.60, also changes the feature names for clients to their simpler variant `surf` and `client`
4047

4148
## [v0.6.1] - 2021-11-23
4249

4350
[Commits](https://github.com/twitch-rs/twitch_oauth2/compare/v0.6.0...v0.6.1)
4451

4552
### Added
4653

47-
* Added new scopes `moderator:manage:automod_settings`, `moderator:manage:banned_users`,
54+
- Added new scopes `moderator:manage:automod_settings`, `moderator:manage:banned_users`,
4855
`moderator:manage:blocked_terms`, `moderator:manage:chat_settings`, `moderator:read:automod_settings`,
4956
`moderator:read:blocked_terms` and `moderator:read:chat_settings`
5057

@@ -54,68 +61,69 @@
5461

5562
### Breaking changes
5663

57-
* All types associated with tokens are now defined in this crate. This is a consequence of the `oauth2` dependency being removed from tree.
64+
- All types associated with tokens are now defined in this crate. This is a consequence of the `oauth2` dependency being removed from tree.
5865
Additionally, as another consequence, clients are now able to be specified as a `for<'a> &'a T where T: Client<'a>`, meaning `twitch_api` can use its clients as an interface to token requests,
5966
and clients can persist instead of being rebuilt every call. Care should be taken when making clients, as SSRF and similar attacks are possible with improper client configurations.
6067

6168
### Added
6269

63-
* Added types/braids `ClientId`, `ClientSecret`, `AccessToken`, `RefreshToken` and `CsrfToken`.
64-
* Added way to interact with the Twitch-CLI [mock API](https://github.com/twitchdev/twitch-cli/blob/main/docs/mock-api.md) using environment variables.
70+
- Added types/braids `ClientId`, `ClientSecret`, `AccessToken`, `RefreshToken` and `CsrfToken`.
71+
- Added way to interact with the Twitch-CLI [mock API](https://github.com/twitchdev/twitch-cli/blob/main/docs/mock-api.md) using environment variables.
6572
See static variables `AUTH_URL`, `TOKEN_URL`, `VALIDATE_URL` and `REVOKE_URL` for more information.
66-
* Added `impl Borrow<str> for Scope`, meaning it can be used in places it couldn't be used before. Primarily, it allows the following code to work:
73+
- Added `impl Borrow<str> for Scope`, meaning it can be used in places it couldn't be used before. Primarily, it allows the following code to work:
6774
```rust
6875
let scopes = vec![Scope::ChatEdit, Scope::ChatRead];
6976
let space_separated_scope: String = scopes.as_slice().join(" ");
7077
```
71-
* Added scope `channel:read:goals`
78+
- Added scope `channel:read:goals`
7279

7380
### Changed
7481

75-
* Requests to `id.twitch.tv` now follow the documentation, instead of following a subset of the RFC for oauth2.
76-
* URLs are now initialized lazily and specified as `url::Url`s.
82+
- Requests to `id.twitch.tv` now follow the documentation, instead of following a subset of the RFC for oauth2.
83+
- URLs are now initialized lazily and specified as `url::Url`s.
7784

7885
### Removed
7986

80-
* Removed `oauth2` dependency.
87+
- Removed `oauth2` dependency.
8188

8289
## [v0.5.2] - 2021-06-18
8390

8491
[Commits](https://github.com/twitch-rs/twitch_oauth2/compare/v0.5.1...v0.5.2)
8592

8693
### Added
8794

88-
* Added new scope `channel:manage:schedule`
95+
- Added new scope `channel:manage:schedule`
8996

9097
## [v0.5.1] - 2021-05-16
9198

9299
[Commits](https://github.com/twitch-rs/twitch_oauth2/compare/v0.5.0...v0.5.1)
93100

94101
### Added
95102

96-
* Added new scopes `channel:manage:polls`, `channel:manage:predictions`, `channel:read:polls`, `channel:read:predictions`, and `moderator:manage:automod`,
97-
* Added function `Scope::description` to get the description of the scope
103+
- Added new scopes `channel:manage:polls`, `channel:manage:predictions`, `channel:read:polls`, `channel:read:predictions`, and `moderator:manage:automod`,
104+
- Added function `Scope::description` to get the description of the scope
98105

99106
## [v0.5.0] - 2021-05-08
100107

101108
[Commits](https://github.com/twitch-rs/twitch_oauth2/compare/49a083ceda6768cc52a1f8f1714bb7f942f24c01...v0.5.0)
102109

103110
### Added
104111

105-
* Made crate runtime agnostic with custom clients.
106-
* Updated deps.
107-
* Add an extra (optional) client secret field to `UserToken::from_existing` (thanks [Dinnerbone](https://github.com/Dinnerbone))
108-
* Added `channel:manage:redemptions`, `channel:read:editors`, `channel:manage:videos`, `user:read:blocked_users`, `user:manage:blocked_users`, `user:read:subscriptions` and `user:read:follows`
109-
* Implemented [OAuth Authorization Code Flow](https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#oauth-authorization-code-flow) with `UserTokenBuilder`
110-
* Added a way to suggest or infer that an user token is never expiring, making `is_elapsed` return false and `expires_in` a bogus (max) duration.
112+
- Made crate runtime agnostic with custom clients.
113+
- Updated deps.
114+
- Add an extra (optional) client secret field to `UserToken::from_existing` (thanks [Dinnerbone](https://github.com/Dinnerbone))
115+
- Added `channel:manage:redemptions`, `channel:read:editors`, `channel:manage:videos`, `user:read:blocked_users`, `user:manage:blocked_users`, `user:read:subscriptions` and `user:read:follows`
116+
- Implemented [OAuth Authorization Code Flow](https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#oauth-authorization-code-flow) with `UserTokenBuilder`
117+
- Added a way to suggest or infer that an user token is never expiring, making `is_elapsed` return false and `expires_in` a bogus (max) duration.
118+
111119
### Changed
112120

113-
* MSRV: 1.51
114-
* Made scope take `Cow<&'static str>`
115-
* Made fields `access_token`, `refresh_token`, `user_id` and `login` `pub` on `UserToken` and `AppAccessToken` (where applicable)
116-
* Fixed wrong scope `user:read:stream_key` -> `channel:read:stream_key`
117-
* BREAKING: changed `TwitchToken::expires` -> `TwitchToken::expires_in` to calculate current lifetime of token
121+
- MSRV: 1.51
122+
- Made scope take `Cow<&'static str>`
123+
- Made fields `access_token`, `refresh_token`, `user_id` and `login` `pub` on `UserToken` and `AppAccessToken` (where applicable)
124+
- Fixed wrong scope `user:read:stream_key` -> `channel:read:stream_key`
125+
- BREAKING: changed `TwitchToken::expires` -> `TwitchToken::expires_in` to calculate current lifetime of token
118126

119127
## End of Changelog
120128

121-
Changelog starts on v0.5.0
129+
Changelog starts on v0.5.0

Cargo.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@ readme = "README.md"
1212
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1313
[features]
1414
default = []
15-
reqwest = ["dep:reqwest"]
16-
surf_client_curl = ["dep:surf", "surf/curl-client"]
17-
surf = ["dep:surf", "dep:http-types", "http-types?/hyperium_http"]
15+
client = ["dep:async-trait"]
16+
reqwest = ["dep:reqwest", "client"]
17+
surf_client_curl = ["surf", "surf/curl-client"]
18+
surf = ["dep:surf", "dep:http-types", "http-types?/hyperium_http", "client"]
1819
mock_api = []
19-
all = ["surf_client_curl", "dep:reqwest"]
20+
all = ["surf_client_curl", "reqwest"]
2021

2122
[dependencies]
2223
thiserror = "1.0.29"
2324
displaydoc = "0.2.3"
2425
serde = { version = "1.0.130", features = ["derive"] }
2526
serde_json = "1.0.68"
26-
async-trait = "0.1.51"
27+
async-trait = { version = "0.1.51", optional = true }
2728
http = "0.2.5"
2829
surf = { version = "2.3.1", optional = true, default-features = false }
2930
reqwest = { version = "0.11.4", optional = true, default-features = false }

release.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,5 @@ pre-release-replacements = [
99
{file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", prerelease=false},
1010
{file="CHANGELOG.md", search="<!-- next-header -->", replace="<!-- next-header -->\n\n## [Unreleased] - ReleaseDate\n\n[Commits](https://github.com/twitch-rs/twitch_oauth2/compare/v{{version}}...Unreleased)", prerelease=false},
1111
{file="README.md", search="twitch_oauth2/[a-z0-9\\.-]+/twitch_oauth2", replace="{{crate_name}}/{{version}}/{{crate_name}}", prerelease=true},
12-
{file="src/lib.rs", search="https://docs.rs/twitch_oauth2/[a-z0-9\\.-]+", replace="https://docs.rs/{{crate_name}}/{{version}}", prerelease=true},
1312
{file="Cargo.toml", search="https://docs.rs/twitch_oauth2/[a-z0-9\\.-]+", replace="https://docs.rs/{{crate_name}}/{{version}}", prerelease=true},
1413
]

src/client.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ pub trait Client<'a>: Sync + Send + 'a {
2020
/// Send a request
2121
fn req(
2222
&'a self,
23-
request: crate::HttpRequest,
24-
) -> BoxedFuture<'a, Result<crate::HttpResponse, <Self as Client>::Error>>;
23+
request: http::Request<Vec<u8>>,
24+
) -> BoxedFuture<'a, Result<http::Response<Vec<u8>>, <Self as Client>::Error>>;
2525
}
2626

2727
#[doc(hidden)]
@@ -35,8 +35,8 @@ impl<'a> Client<'a> for DummyClient {
3535

3636
fn req(
3737
&'a self,
38-
_: crate::HttpRequest,
39-
) -> BoxedFuture<'a, Result<crate::HttpResponse, Self::Error>> {
38+
_: http::Request<Vec<u8>>,
39+
) -> BoxedFuture<'a, Result<http::Response<Vec<u8>>, Self::Error>> {
4040
Box::pin(async move { Err(self.clone()) })
4141
}
4242
}
@@ -49,8 +49,8 @@ impl<'a> Client<'a> for ReqwestClient {
4949

5050
fn req(
5151
&'a self,
52-
request: crate::HttpRequest,
53-
) -> BoxedFuture<'a, Result<crate::HttpResponse, Self::Error>> {
52+
request: http::Request<Vec<u8>>,
53+
) -> BoxedFuture<'a, Result<http::Response<Vec<u8>>, Self::Error>> {
5454
// Reqwest plays really nice here and has a try_from on `http::Request` -> `reqwest::Request`
5555
let req = match reqwest::Request::try_from(request) {
5656
Ok(req) => req,
@@ -98,8 +98,8 @@ impl<'a> Client<'a> for SurfClient {
9898

9999
fn req(
100100
&'a self,
101-
request: crate::HttpRequest,
102-
) -> BoxedFuture<'a, Result<crate::HttpResponse, Self::Error>> {
101+
request: http::Request<Vec<u8>>,
102+
) -> BoxedFuture<'a, Result<http::Response<Vec<u8>>, Self::Error>> {
103103
// First we translate the `http::Request` method and uri into types that surf understands.
104104

105105
let method: surf::http::Method = request.method().clone().into();
@@ -124,7 +124,7 @@ impl<'a> Client<'a> for SurfClient {
124124
}
125125

126126
// assembly the request, now we can send that to our `surf::Client`
127-
req.body_bytes(&request.body());
127+
req.body_bytes(request.body());
128128

129129
let client = self.clone();
130130
Box::pin(async move {

src/id.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
33
use serde::{Deserialize, Serialize};
44

5-
use crate::AccessToken;
5+
use crate::{AccessToken, RequestParseError};
66
use std::time::Duration;
77
/// Twitch's representation of the oauth flow.
8+
///
9+
/// Retrieve with
10+
///
11+
/// * [`UserTokenBuilder::get_user_token_request`](crate::tokens::UserTokenBuilder::get_user_token_request)
12+
/// * [`AppAccessToken::::get_app_access_token_request`](crate::tokens::AppAccessToken::get_app_access_token_request)
813
#[derive(Clone, Debug, Deserialize, Serialize)]
914
pub struct TwitchTokenResponse {
1015
/// Access token
@@ -21,6 +26,15 @@ pub struct TwitchTokenResponse {
2126
pub scopes: Option<Vec<crate::Scope>>,
2227
}
2328

29+
impl TwitchTokenResponse {
30+
/// Create a [TwitchTokenResponse] from a [http::Response]
31+
pub fn from_response<B: AsRef<[u8]>>(
32+
response: &http::Response<B>,
33+
) -> Result<TwitchTokenResponse, RequestParseError> {
34+
crate::parse_response(response)
35+
}
36+
}
37+
2438
/// Twitch's representation of the oauth flow for errors
2539
#[derive(Clone, Debug, Deserialize, Serialize, thiserror::Error)]
2640
pub struct TwitchTokenErrorResponse {

0 commit comments

Comments
 (0)