Skip to content

Commit c40363e

Browse files
committed
better oauth token serialization
1 parent 985c301 commit c40363e

3 files changed

Lines changed: 38 additions & 5 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ serde_json = "1.0"
1818
serde_urlencoded = "0.7"
1919
strum = { version = "0.24", features = ["derive"] }
2020
thiserror = "1.0"
21+
time = { version = "0.3", features = ["serde", "serde-well-known"] }
2122
tokio = { version = "1.0", default-features = false, features = ["sync"] }
2223
url = "2.2"
2324

examples/oauth2_callback.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,20 @@ async fn revoke(Extension(ctx): Extension<Arc<Mutex<Oauth2Ctx>>>) -> impl IntoRe
127127
Ok::<_, (StatusCode, String)>("Token revoked!")
128128
}
129129

130+
async fn debug_token(Extension(ctx): Extension<Arc<Mutex<Oauth2Ctx>>>) -> impl IntoResponse {
131+
// get oauth token
132+
let oauth_token = ctx
133+
.lock()
134+
.unwrap()
135+
.token
136+
.as_ref()
137+
.ok_or_else(|| (StatusCode::UNAUTHORIZED, "User not logged in!".to_string()))?
138+
.clone();
139+
// get underlying token
140+
let serializable_token = oauth_token.token().await.clone();
141+
Ok::<_, (StatusCode, String)>(Json(serializable_token))
142+
}
143+
130144
#[tokio::main]
131145
async fn main() {
132146
// initialize tracing
@@ -159,6 +173,7 @@ async fn main() {
159173
.route("/callback", get(callback))
160174
.route("/tweets", get(tweets))
161175
.route("/revoke", get(revoke))
176+
.route("/debug_token", get(debug_token))
162177
.layer(TraceLayer::new_for_http())
163178
.layer(Extension(Arc::new(Mutex::new(oauth_ctx))));
164179

src/authorization/oauth2.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,45 +12,61 @@ use reqwest::Request;
1212
use serde::{Deserialize, Serialize};
1313
use std::convert::{TryFrom, TryInto};
1414
use std::sync::Arc;
15-
use std::time::SystemTime;
1615
use strum::{Display, EnumString};
16+
use time::OffsetDateTime;
1717
use tokio::sync::{RwLock, RwLockReadGuard};
1818
use url::Url;
1919

2020
#[derive(Copy, Clone, Debug, EnumString, Display, Serialize, Deserialize)]
2121
#[strum(serialize_all = "snake_case")]
2222
pub enum Scope {
2323
#[strum(serialize = "tweet.read")]
24+
#[serde(rename = "tweet.read")]
2425
TweetRead,
2526
#[strum(serialize = "tweet.write")]
27+
#[serde(rename = "tweet.write")]
2628
TweetWrite,
2729
#[strum(serialize = "tweet.moderate.write")]
30+
#[serde(rename = "tweet.moderate.write")]
2831
TweetModerateWrite,
2932
#[strum(serialize = "users.read")]
33+
#[serde(rename = "users.read")]
3034
UsersRead,
3135
#[strum(serialize = "follows.read")]
36+
#[serde(rename = "follows.read")]
3237
FollowsRead,
3338
#[strum(serialize = "follows.write")]
39+
#[serde(rename = "follows.write")]
3440
FollowsWrite,
3541
#[strum(serialize = "offline.access")]
42+
#[serde(rename = "offline.access")]
3643
OfflineAccess,
3744
#[strum(serialize = "space.read")]
45+
#[serde(rename = "space.read")]
3846
SpaceRead,
3947
#[strum(serialize = "mute.read")]
48+
#[serde(rename = "mute.read")]
4049
MuteRead,
4150
#[strum(serialize = "mute.write")]
51+
#[serde(rename = "mute.write")]
4252
MuteWrite,
4353
#[strum(serialize = "like.read")]
54+
#[serde(rename = "like.read")]
4455
LikeRead,
4556
#[strum(serialize = "like.write")]
57+
#[serde(rename = "like.write")]
4658
LikeWrite,
4759
#[strum(serialize = "list.read")]
60+
#[serde(rename = "list.read")]
4861
ListRead,
4962
#[strum(serialize = "list.write")]
63+
#[serde(rename = "list.write")]
5064
ListWrite,
5165
#[strum(serialize = "block.read")]
66+
#[serde(rename = "block.read")]
5267
BlockRead,
5368
#[strum(serialize = "block.write")]
69+
#[serde(rename = "block.write")]
5470
BlockWrite,
5571
}
5672

@@ -129,7 +145,8 @@ impl Oauth2Client {
129145
pub struct Oauth2Token {
130146
access_token: AccessToken,
131147
refresh_token: Option<RefreshToken>,
132-
expires: SystemTime,
148+
#[serde(with = "time::serde::rfc3339")]
149+
expires: OffsetDateTime,
133150
scopes: Vec<Scope>,
134151
}
135152

@@ -140,11 +157,11 @@ impl Oauth2Token {
140157
pub fn refresh_token(&self) -> Option<&RefreshToken> {
141158
self.refresh_token.as_ref()
142159
}
143-
pub fn expires(&self) -> SystemTime {
160+
pub fn expires(&self) -> OffsetDateTime {
144161
self.expires
145162
}
146163
pub fn is_expired(&self) -> bool {
147-
self.expires < SystemTime::now()
164+
self.expires < OffsetDateTime::now_utc()
148165
}
149166
pub fn scopes(&self) -> &[Scope] {
150167
&self.scopes
@@ -164,7 +181,7 @@ impl TryFrom<BasicTokenResponse> for Oauth2Token {
164181
Ok(Self {
165182
access_token: token.access_token().clone(),
166183
refresh_token: token.refresh_token().cloned(),
167-
expires: SystemTime::now()
184+
expires: OffsetDateTime::now_utc()
168185
+ token.expires_in().ok_or_else(|| {
169186
Error::Oauth2TokenError(BasicRequestTokenError::Other(
170187
"Missing expiration".to_string(),

0 commit comments

Comments
 (0)