Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Claims] Add all possible backend claims to ClerkJWT #56

Merged
merged 2 commits into from
Jul 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/validators/authorizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,33 @@ use crate::{
use jsonwebtoken::{decode, decode_header, errors::Error as jwtError, Algorithm, DecodingKey, Header, Validation};
use std::{error::Error, fmt};

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct ActiveOrganization {
#[serde(rename = "org_id")]
id: String,
#[serde(rename = "org_slug")]
slug: String,
#[serde(rename = "org_role")]
role: String,
#[serde(rename = "org_permissions")]
permissions: Vec<String>,
}

impl ActiveOrganization {
/// Checks if the user has the specific permission in their session claims.
pub fn has_permission(&self, permission: &str) -> bool {
self.permissions.contains(&permission.to_string())
}

/// Checks if the user has the specific role in their session claims.
/// Performing role checks is not considered a best-practice and developers
/// should avoid it as much as possible. Usually, complex role checks can be
/// refactored with a single permission check.
pub fn has_role(&self, role: &str) -> bool {
self.role == role
}
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct ClerkJwt {
pub azp: Option<String>,
Expand All @@ -14,6 +41,9 @@ pub struct ClerkJwt {
pub nbf: i32,
pub sid: Option<String>,
pub sub: String,
pub act: Option<String>,
kageiit marked this conversation as resolved.
Show resolved Hide resolved
#[serde(flatten)]
pub org: Option<ActiveOrganization>,
}

pub trait ClerkRequest {
Expand Down Expand Up @@ -147,6 +177,11 @@ mod tests {
azp: String,
iss: String,
sid: String,
act: String,
org_id: String,
org_slug: String,
org_role: String,
org_permissions: Vec<String>,
}

struct Helper {
Expand Down Expand Up @@ -181,6 +216,11 @@ mod tests {
iss: "issuer".to_string(),
nbf: current_time,
sid: "session_id".to_string(),
act: "actor".to_string(),
org_id: "org_id".to_string(),
org_slug: "org_slug".to_string(),
org_role: "org_role".to_string(),
org_permissions: vec!["org_permission".to_string()],
};

let mut header = Header::new(Algorithm::RS256);
Expand Down Expand Up @@ -229,6 +269,13 @@ mod tests {
iss: "issuer".to_string(),
nbf: current_time as i32,
sid: Some("session_id".to_string()),
act: Some("actor".to_string()),
org: Some(ActiveOrganization {
id: "org_id".to_string(),
slug: "org_slug".to_string(),
role: "org_role".to_string(),
permissions: vec!["org_permission".to_string()],
}),
};

match validate_jwt(token.as_str(), jwks) {
Expand Down
Loading