summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrw1593 <botahamec@outlook.com>2023-07-02 11:52:50 -0400
committermrw1593 <botahamec@outlook.com>2023-07-02 11:52:50 -0400
commit15a7387309fed7dcc589216aac748811e0321ab4 (patch)
tree0541ba37a9b5e01e3c03dcf31b0b2df234d1bf49
parentb909c8496a7e0f035623105f631809ef3016a810 (diff)
Changes to jwt claims
-rw-r--r--src/api/oauth.rs43
-rw-r--r--src/services/jwt.rs55
2 files changed, 57 insertions, 41 deletions
diff --git a/src/api/oauth.rs b/src/api/oauth.rs
index fe1c361..aee0ed4 100644
--- a/src/api/oauth.rs
+++ b/src/api/oauth.rs
@@ -216,12 +216,16 @@ async fn authenticate_user(
db: &MySqlPool,
username: &str,
password: &str,
-) -> Result<bool, RawUnexpected> {
+) -> Result<Option<Uuid>, RawUnexpected> {
let Some(user) = db::get_user_by_username(db, username).await? else {
- return Ok(false);
+ return Ok(None);
};
- Ok(user.check_password(password)?)
+ if user.check_password(password)? {
+ Ok(Some(user.id))
+ } else {
+ Ok(None)
+ }
}
#[post("/authorize")]
@@ -248,7 +252,7 @@ async fn authorize(
return HttpResponse::InternalServerError().content_type("text/html").body(page);
};
- let self_id = config.id;
+ let self_id = config.url;
let state = req.state.clone();
// get redirect uri
@@ -267,9 +271,9 @@ async fn authorize(
};
// authenticate user
- if !authenticate_user(db, &credentials.username, &credentials.password)
+ let Some(user_id) = authenticate_user(db, &credentials.username, &credentials.password)
.await
- .unwrap()
+ .unwrap() else
{
let language = Language::from_str("en").unwrap();
let translations = translations.get_ref().clone();
@@ -289,9 +293,10 @@ async fn authorize(
match req.response_type {
ResponseType::Code => {
// create auth code
- let code = jwt::Claims::auth_code(db, &self_id, client_id, &scope, &redirect_uri)
- .await
- .unwrap();
+ let code =
+ jwt::Claims::auth_code(db, self_id, client_id, user_id, &scope, &redirect_uri)
+ .await
+ .unwrap();
let code = code.to_jwt().unwrap();
let response = AuthCodeResponse { code, state };
@@ -307,7 +312,7 @@ async fn authorize(
// create access token
let duration = Duration::hours(1);
let access_token =
- jwt::Claims::access_token(db, None, &self_id, client_id, duration, &scope)
+ jwt::Claims::access_token(db, None, self_id, client_id, user_id, duration, &scope)
.await
.unwrap();
@@ -635,7 +640,7 @@ async fn token(
};
let config = config::get_config().unwrap();
- let self_id = config.id;
+ let self_id = config.url;
let duration = Duration::hours(1);
let token_type = Box::from("bearer");
let cache_control = header::CacheControl(vec![header::CacheDirective::NoStore]);
@@ -677,8 +682,9 @@ async fn token(
let access_token = jwt::Claims::access_token(
db,
Some(claims.id()),
- &self_id,
+ self_id,
client_id,
+ claims.subject(),
duration,
claims.scopes(),
)
@@ -729,7 +735,7 @@ async fn token(
}
// authenticate user
- if !authenticate_user(db, &username, &password).await.unwrap() {
+ let Some(user_id) = authenticate_user(db, &username, &password).await.unwrap() else {
return TokenError::incorrect_user_credentials().error_response();
};
@@ -755,7 +761,7 @@ async fn token(
}
let access_token =
- jwt::Claims::access_token(db, None, &self_id, client_id, duration, &scope)
+ jwt::Claims::access_token(db, None, self_id, client_id, user_id, duration, &scope)
.await
.unwrap();
let refresh_token = jwt::Claims::refresh_token(db, &access_token).await.unwrap();
@@ -818,10 +824,11 @@ async fn token(
return TokenError::excessive_scope().error_response();
}
- let access_token =
- jwt::Claims::access_token(db, None, &self_id, client_id, duration, &scope)
- .await
- .unwrap();
+ let access_token = jwt::Claims::access_token(
+ db, None, self_id, client_id, client_id, duration, &scope,
+ )
+ .await
+ .unwrap();
let expires_in = access_token.expires_in();
let scope = access_token.scopes().into();
diff --git a/src/services/jwt.rs b/src/services/jwt.rs
index 489b32f..16f5fa6 100644
--- a/src/services/jwt.rs
+++ b/src/services/jwt.rs
@@ -19,14 +19,15 @@ pub enum TokenType {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Claims {
- iss: Box<str>,
+ iss: Url,
+ sub: Uuid,
aud: Box<[String]>,
#[serde(with = "ts_milliseconds")]
exp: DateTime<Utc>,
#[serde(with = "ts_milliseconds_option")]
nbf: Option<DateTime<Utc>>,
- #[serde(with = "ts_milliseconds_option")]
- iat: Option<DateTime<Utc>>,
+ #[serde(with = "ts_milliseconds")]
+ iat: DateTime<Utc>,
jti: Uuid,
scope: Box<str>,
client_id: Uuid,
@@ -45,27 +46,29 @@ pub enum RevokedRefreshTokenReason {
impl Claims {
pub async fn auth_code<'c>(
db: &MySqlPool,
- self_id: &str,
+ self_id: Url,
client_id: Uuid,
+ sub: Uuid,
scopes: &str,
redirect_uri: &Url,
) -> Result<Self, RawUnexpected> {
let five_minutes = Duration::minutes(5);
let id = new_id(db, db::auth_code_exists).await?;
- let time = Utc::now();
- let exp = time + five_minutes;
+ let iat = Utc::now();
+ let exp = iat + five_minutes;
db::create_auth_code(db, id, exp).await?;
let aud = [self_id.to_string(), client_id.to_string()].into();
Ok(Self {
- iss: Box::from(self_id),
+ iss: self_id,
+ sub,
aud,
exp,
nbf: None,
- iat: Some(time),
+ iat,
jti: id,
scope: scopes.into(),
client_id,
@@ -78,14 +81,15 @@ impl Claims {
pub async fn access_token<'c>(
db: &MySqlPool,
auth_code_id: Option<Uuid>,
- self_id: &str,
+ self_id: Url,
client_id: Uuid,
+ sub: Uuid,
duration: Duration,
scopes: &str,
) -> Result<Self, RawUnexpected> {
let id = new_id(db, db::access_token_exists).await?;
- let time = Utc::now();
- let exp = time + duration;
+ let iat = Utc::now();
+ let exp = iat + duration;
db::create_access_token(db, id, auth_code_id, exp)
.await
@@ -94,11 +98,12 @@ impl Claims {
let aud = [self_id.to_string(), client_id.to_string()].into();
Ok(Self {
- iss: Box::from(self_id),
+ iss: self_id,
+ sub,
aud,
exp,
nbf: None,
- iat: Some(time),
+ iat,
jti: id,
scope: scopes.into(),
client_id,
@@ -115,14 +120,14 @@ impl Claims {
let one_day = Duration::days(1);
let id = new_id(db, db::refresh_token_exists).await?;
- let time = Utc::now();
+ let iat = Utc::now();
let exp = other_token.exp + one_day;
db::create_refresh_token(db, id, other_token.auth_code_id, exp).await?;
let mut claims = other_token.clone();
claims.exp = exp;
- claims.iat = Some(time);
+ claims.iat = iat;
claims.jti = id;
claims.token_type = TokenType::Refresh;
@@ -135,14 +140,14 @@ impl Claims {
exp_time: Duration,
) -> Result<Self, RawUnexpected> {
let id = new_id(db, db::access_token_exists).await?;
- let time = Utc::now();
- let exp = time + exp_time;
+ let iat = Utc::now();
+ let exp = iat + exp_time;
db::create_access_token(db, id, refresh_token.auth_code_id, exp).await?;
let mut claims = refresh_token.clone();
claims.exp = exp;
- claims.iat = Some(time);
+ claims.iat = iat;
claims.jti = id;
claims.token_type = TokenType::Access;
@@ -153,6 +158,10 @@ impl Claims {
self.jti
}
+ pub fn subject(&self) -> Uuid {
+ self.sub
+ }
+
pub fn expires_in(&self) -> i64 {
(self.exp - Utc::now()).num_seconds()
}
@@ -190,7 +199,7 @@ pub enum VerifyJwtError {
fn verify_jwt(
token: &str,
- self_id: &str,
+ self_id: &Url,
client_id: Option<Uuid>,
) -> Result<Claims, Expect<VerifyJwtError>> {
let key = secrets::signing_key()?;
@@ -198,7 +207,7 @@ fn verify_jwt(
.verify_with_key(&key)
.map_err(|e| VerifyJwtError::from(e))?;
- if claims.iss != self_id.into() {
+ if &claims.iss != self_id {
yeet!(VerifyJwtError::IncorrectIssuer.into())
}
@@ -230,7 +239,7 @@ fn verify_jwt(
pub async fn verify_auth_code<'c>(
db: &MySqlPool,
token: &str,
- self_id: &str,
+ self_id: &Url,
client_id: Uuid,
redirect_uri: Url,
) -> Result<Claims, Expect<VerifyJwtError>> {
@@ -254,7 +263,7 @@ pub async fn verify_auth_code<'c>(
pub async fn verify_access_token<'c>(
db: impl Executor<'c, Database = MySql>,
token: &str,
- self_id: &str,
+ self_id: &Url,
client_id: Uuid,
) -> Result<Claims, Expect<VerifyJwtError>> {
let claims = verify_jwt(token, self_id, Some(client_id))?;
@@ -269,7 +278,7 @@ pub async fn verify_access_token<'c>(
pub async fn verify_refresh_token<'c>(
db: impl Executor<'c, Database = MySql>,
token: &str,
- self_id: &str,
+ self_id: &Url,
client_id: Option<Uuid>,
) -> Result<Claims, Expect<VerifyJwtError>> {
let claims = verify_jwt(token, self_id, client_id)?;