Skip to content
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
38 changes: 35 additions & 3 deletions contracts/jwt-guards/jwt-guard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod config;
mod error;
mod utils;

const JWT_CLAIM_STORAGE: u128 = 128;
const JWT_CLAIM_STORAGE: u128 = 256;

#[near(serializers = [json])]
#[derive(AccessControlRole, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down Expand Up @@ -56,13 +56,15 @@ impl Role {
pub struct CustomIssuerGuard {
public_keys: Vec<JwtPublicKey>,
jwt_claims: near_sdk::store::LookupMap<AccountId, Vec<u8>>,
jwt_hash_claims: near_sdk::store::LookupMap<Vec<u8>, AccountId>,
account_storage_usage: U128,
}

#[derive(near_sdk::BorshStorageKey)]
#[near(serializers = [borsh])]
pub enum Prefix {
JwtClaims,
JwtHashClaims,
}

#[near(serializers = [json, borsh])]
Expand All @@ -85,6 +87,7 @@ impl CustomIssuerGuard {
let mut this = Self {
public_keys: config.public_keys,
jwt_claims: near_sdk::store::LookupMap::new(Prefix::JwtClaims),
jwt_hash_claims: near_sdk::store::LookupMap::new(Prefix::JwtHashClaims),
account_storage_usage: U128(JWT_CLAIM_STORAGE),
};
this.init_acl(config.roles);
Expand Down Expand Up @@ -146,8 +149,14 @@ impl CustomIssuerGuard {
pub fn claim_oidc(&mut self, oidc_token_hash: Vec<u8>) {
assert_eq!(oidc_token_hash.len(), 32, "OIDC token hash must be 32 bytes");
let account_id = env::predecessor_account_id();
self.internal_unwrap_jwt_claim(&account_id);
self.jwt_claims.insert(account_id, oidc_token_hash);

assert!(!self.exist_jwt_hash_claim(&oidc_token_hash), "OIDC token hash already claimed");

let hash = self.internal_unwrap_jwt_claim(&account_id);
self.jwt_hash_claims.remove(&hash.clone());

self.jwt_claims.insert(account_id.clone(), oidc_token_hash.clone());
self.jwt_hash_claims.insert(oidc_token_hash, account_id);
}

/// Gets the JWT claim of an account
Expand All @@ -162,6 +171,18 @@ impl CustomIssuerGuard {
self.jwt_claims.get(account_id).cloned()
}

/// Gets the account that claimed a JWT claim by its hash
///
/// # Arguments
/// * `hash` - The hash of the JWT claim for which to get the account
///
/// # Returns
/// * `Option<AccountId>` - The account ID of the account that claimed the JWT claim, if it exists, or `None` otherwise
///
pub fn jwt_hash_claim_of(&self, hash: &Vec<u8>) -> Option<AccountId> {
self.jwt_hash_claims.get(hash).cloned()
}

/// Updates the public keys used for JWT verification
/// # Arguments
/// * `public_keys` - The new RSA public key components to use for verification
Expand Down Expand Up @@ -191,6 +212,17 @@ impl CustomIssuerGuard {
}
}

///
/// # Arguments
/// * `hash` - The hash of the jwt claim to check for
///
/// # Returns
/// * `bool` - True if jwt hash claim exists, false otherwise
///
fn exist_jwt_hash_claim(&self, hash: &Vec<u8>) -> bool {
self.jwt_hash_claims.get(hash).is_some()
}

/// Verifies a JWT token and its custom claims
///
/// # Arguments
Expand Down
Loading