Reorganise tests
This commit is contained in:
parent
caef740ad4
commit
210e96063d
|
@ -8,6 +8,7 @@
|
|||
- Update to 2018 edition
|
||||
- Changed aud field type in Validation to `Option<HashSet<String>>`. Audience
|
||||
validation now tests for "any-of-these" audience membership.
|
||||
- Add support for keys in PEM format
|
||||
|
||||
## 6.0.1 (2019-05-10)
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@ serde_json = "1.0"
|
|||
serde_derive = "1.0"
|
||||
serde = "1.0"
|
||||
ring = { version = "0.16.5", features = ["std"] }
|
||||
base64 = "0.10"
|
||||
base64 = "0.11"
|
||||
# For validation
|
||||
chrono = "0.4"
|
||||
# For PEM decoding
|
||||
pem = "0.7"
|
||||
simple_asn1 = "0.4.0"
|
||||
simple_asn1 = "0.4"
|
||||
|
|
|
@ -56,3 +56,22 @@ impl FromStr for Algorithm {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn generate_algorithm_enum_from_str() {
|
||||
assert!(Algorithm::from_str("HS256").is_ok());
|
||||
assert!(Algorithm::from_str("HS384").is_ok());
|
||||
assert!(Algorithm::from_str("HS512").is_ok());
|
||||
assert!(Algorithm::from_str("RS256").is_ok());
|
||||
assert!(Algorithm::from_str("RS384").is_ok());
|
||||
assert!(Algorithm::from_str("RS512").is_ok());
|
||||
assert!(Algorithm::from_str("PS256").is_ok());
|
||||
assert!(Algorithm::from_str("PS384").is_ok());
|
||||
assert!(Algorithm::from_str("PS512").is_ok());
|
||||
assert!(Algorithm::from_str("").is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -403,4 +403,28 @@ mod tests {
|
|||
_ => assert!(false),
|
||||
};
|
||||
}
|
||||
|
||||
// https://github.com/Keats/jsonwebtoken/issues/51
|
||||
#[test]
|
||||
fn does_validation_in_right_order() {
|
||||
let mut claims = Map::new();
|
||||
claims.insert("exp".to_string(), to_value(Utc::now().timestamp() + 10000).unwrap());
|
||||
let v = Validation {
|
||||
leeway: 5,
|
||||
validate_exp: true,
|
||||
iss: Some("iss no check".to_string()),
|
||||
sub: Some("sub no check".to_string()),
|
||||
..Validation::default()
|
||||
};
|
||||
let res = validate(&claims, &v);
|
||||
// It errors because it needs to validate iss/sub which are missing
|
||||
assert!(res.is_err());
|
||||
match res.unwrap_err().kind() {
|
||||
&ErrorKind::InvalidIssuer => (),
|
||||
t @ _ => {
|
||||
println!("{:?}", t);
|
||||
assert!(false)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
extern crate jsonwebtoken;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate chrono;
|
||||
|
||||
use chrono::Utc;
|
||||
use jsonwebtoken::{decode, decode_pem, encode, sign, verify, Algorithm, Header, Key, Validation};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct Claims {
|
||||
|
@ -49,10 +45,3 @@ fn round_trip_claim() {
|
|||
assert_eq!(my_claims, token_data.claims);
|
||||
assert!(token_data.header.kid.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidKeyFormat")]
|
||||
fn fails_with_non_pkcs8_key_format() {
|
||||
let privkey = include_bytes!("private_rsa_key.der");
|
||||
let _encrypted = sign("hello world", Key::Der(&privkey[..]), Algorithm::ES256).unwrap();
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
use chrono::Utc;
|
||||
use jsonwebtoken::{
|
||||
dangerous_unsafe_decode, decode, decode_header, encode, sign, verify, Algorithm, Header, Key,
|
||||
Validation,
|
||||
};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct Claims {
|
||||
sub: String,
|
||||
company: String,
|
||||
exp: i64,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_hs256() {
|
||||
let result = sign("hello world", Key::Hmac(b"secret"), Algorithm::HS256).unwrap();
|
||||
let expected = "c0zGLzKEFWj0VxWuufTXiRMk5tlI5MbGDAYhzaxIYjo";
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_hs256() {
|
||||
let sig = "c0zGLzKEFWj0VxWuufTXiRMk5tlI5MbGDAYhzaxIYjo";
|
||||
let valid = verify(sig, "hello world", Key::Hmac(b"secret"), Algorithm::HS256).unwrap();
|
||||
assert!(valid);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_with_custom_header() {
|
||||
let my_claims = Claims {
|
||||
sub: "b@b.com".to_string(),
|
||||
company: "ACME".to_string(),
|
||||
exp: Utc::now().timestamp() + 10000,
|
||||
};
|
||||
let mut header = Header::default();
|
||||
header.kid = Some("kid".to_string());
|
||||
let token = encode(&header, &my_claims, Key::Hmac(b"secret")).unwrap();
|
||||
let token_data =
|
||||
decode::<Claims>(&token, Key::Hmac(b"secret"), &Validation::default()).unwrap();
|
||||
assert_eq!(my_claims, token_data.claims);
|
||||
assert_eq!("kid", token_data.header.kid.unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip_claim() {
|
||||
let my_claims = Claims {
|
||||
sub: "b@b.com".to_string(),
|
||||
company: "ACME".to_string(),
|
||||
exp: Utc::now().timestamp() + 10000,
|
||||
};
|
||||
let token = encode(&Header::default(), &my_claims, Key::Hmac(b"secret")).unwrap();
|
||||
let token_data =
|
||||
decode::<Claims>(&token, Key::Hmac(b"secret"), &Validation::default()).unwrap();
|
||||
assert_eq!(my_claims, token_data.claims);
|
||||
assert!(token_data.header.kid.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_token() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.9r56oF7ZliOBlOAyiOFperTGxBtPykRQiWNFxhDCW98";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"secret"), &Validation::default());
|
||||
println!("{:?}", claims);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidToken")]
|
||||
fn decode_token_missing_parts() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"secret"), &Validation::default());
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidSignature")]
|
||||
fn decode_token_invalid_signature() {
|
||||
let token =
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.wrong";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"secret"), &Validation::default());
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidAlgorithm")]
|
||||
fn decode_token_wrong_algorithm() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.I1BvFoHe94AFf09O6tDbcSB8-jp8w6xZqmyHIwPeSdY";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"secret"), &Validation::new(Algorithm::RS512));
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_token_with_bytes_secret() {
|
||||
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.Hm0yvKH25TavFPz7J_coST9lZFYH1hQo0tvhvImmaks";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"\x01\x02\x03"), &Validation::default());
|
||||
assert!(claims.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_header_only() {
|
||||
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb21wYW55IjoiMTIzNDU2Nzg5MCIsInN1YiI6IkpvaG4gRG9lIn0.S";
|
||||
let header = decode_header(token).unwrap();
|
||||
assert_eq!(header.alg, Algorithm::HS256);
|
||||
assert_eq!(header.typ, Some("JWT".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dangerous_unsafe_decode_token() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.9r56oF7ZliOBlOAyiOFperTGxBtPykRQiWNFxhDCW98";
|
||||
let claims = dangerous_unsafe_decode::<Claims>(token);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidToken")]
|
||||
fn dangerous_unsafe_decode_token_missing_parts() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
|
||||
let claims = dangerous_unsafe_decode::<Claims>(token);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dangerous_unsafe_decode_token_invalid_signature() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.wrong";
|
||||
let claims = dangerous_unsafe_decode::<Claims>(token);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dangerous_unsafe_decode_token_wrong_algorithm() {
|
||||
let token = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.fLxey-hxAKX5rNHHIx1_Ch0KmrbiuoakDVbsJjLWrx8fbjKjrPuWMYEJzTU3SBnYgnZokC-wqSdqckXUOunC-g";
|
||||
let claims = dangerous_unsafe_decode::<Claims>(token);
|
||||
claims.unwrap();
|
||||
}
|
177
tests/lib.rs
177
tests/lib.rs
|
@ -1,175 +1,2 @@
|
|||
extern crate jsonwebtoken;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate chrono;
|
||||
|
||||
use chrono::Utc;
|
||||
use jsonwebtoken::{
|
||||
dangerous_unsafe_decode, decode, decode_header, encode, sign, verify, Algorithm, Header, Key,
|
||||
Validation,
|
||||
};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct Claims {
|
||||
sub: String,
|
||||
company: String,
|
||||
exp: i64,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_hs256() {
|
||||
let result = sign("hello world", Key::Hmac(b"secret"), Algorithm::HS256).unwrap();
|
||||
let expected = "c0zGLzKEFWj0VxWuufTXiRMk5tlI5MbGDAYhzaxIYjo";
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_hs256() {
|
||||
let sig = "c0zGLzKEFWj0VxWuufTXiRMk5tlI5MbGDAYhzaxIYjo";
|
||||
let valid = verify(sig, "hello world", Key::Hmac(b"secret"), Algorithm::HS256).unwrap();
|
||||
assert!(valid);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_with_custom_header() {
|
||||
let my_claims = Claims {
|
||||
sub: "b@b.com".to_string(),
|
||||
company: "ACME".to_string(),
|
||||
exp: Utc::now().timestamp() + 10000,
|
||||
};
|
||||
let mut header = Header::default();
|
||||
header.kid = Some("kid".to_string());
|
||||
let token = encode(&header, &my_claims, Key::Hmac(b"secret")).unwrap();
|
||||
let token_data =
|
||||
decode::<Claims>(&token, Key::Hmac(b"secret"), &Validation::default()).unwrap();
|
||||
assert_eq!(my_claims, token_data.claims);
|
||||
assert_eq!("kid", token_data.header.kid.unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip_claim() {
|
||||
let my_claims = Claims {
|
||||
sub: "b@b.com".to_string(),
|
||||
company: "ACME".to_string(),
|
||||
exp: Utc::now().timestamp() + 10000,
|
||||
};
|
||||
let token = encode(&Header::default(), &my_claims, Key::Hmac(b"secret")).unwrap();
|
||||
let token_data =
|
||||
decode::<Claims>(&token, Key::Hmac(b"secret"), &Validation::default()).unwrap();
|
||||
assert_eq!(my_claims, token_data.claims);
|
||||
assert!(token_data.header.kid.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_token() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.9r56oF7ZliOBlOAyiOFperTGxBtPykRQiWNFxhDCW98";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"secret"), &Validation::default());
|
||||
println!("{:?}", claims);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidToken")]
|
||||
fn decode_token_missing_parts() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"secret"), &Validation::default());
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidSignature")]
|
||||
fn decode_token_invalid_signature() {
|
||||
let token =
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.wrong";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"secret"), &Validation::default());
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidAlgorithm")]
|
||||
fn decode_token_wrong_algorithm() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.I1BvFoHe94AFf09O6tDbcSB8-jp8w6xZqmyHIwPeSdY";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"secret"), &Validation::new(Algorithm::RS512));
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_token_with_bytes_secret() {
|
||||
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.Hm0yvKH25TavFPz7J_coST9lZFYH1hQo0tvhvImmaks";
|
||||
let claims = decode::<Claims>(token, Key::Hmac(b"\x01\x02\x03"), &Validation::default());
|
||||
assert!(claims.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_header_only() {
|
||||
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb21wYW55IjoiMTIzNDU2Nzg5MCIsInN1YiI6IkpvaG4gRG9lIn0.S";
|
||||
let header = decode_header(token).unwrap();
|
||||
assert_eq!(header.alg, Algorithm::HS256);
|
||||
assert_eq!(header.typ, Some("JWT".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dangerous_unsafe_decode_token() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.9r56oF7ZliOBlOAyiOFperTGxBtPykRQiWNFxhDCW98";
|
||||
let claims = dangerous_unsafe_decode::<Claims>(token);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidToken")]
|
||||
fn dangerous_unsafe_decode_token_missing_parts() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
|
||||
let claims = dangerous_unsafe_decode::<Claims>(token);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dangerous_unsafe_decode_token_invalid_signature() {
|
||||
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.wrong";
|
||||
let claims = dangerous_unsafe_decode::<Claims>(token);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dangerous_unsafe_decode_token_wrong_algorithm() {
|
||||
let token = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.fLxey-hxAKX5rNHHIx1_Ch0KmrbiuoakDVbsJjLWrx8fbjKjrPuWMYEJzTU3SBnYgnZokC-wqSdqckXUOunC-g";
|
||||
let claims = dangerous_unsafe_decode::<Claims>(token);
|
||||
claims.unwrap();
|
||||
}
|
||||
|
||||
// https://github.com/Keats/jsonwebtoken/issues/51
|
||||
#[test]
|
||||
fn does_validation_in_right_order() {
|
||||
let my_claims = Claims {
|
||||
sub: "b@b.com".to_string(),
|
||||
company: "ACME".to_string(),
|
||||
exp: Utc::now().timestamp() + 10000,
|
||||
};
|
||||
let token = encode(&Header::default(), &my_claims, Key::Hmac(b"secret")).unwrap();
|
||||
let v = Validation {
|
||||
leeway: 5,
|
||||
validate_exp: true,
|
||||
iss: Some("iss no check".to_string()),
|
||||
sub: Some("sub no check".to_string()),
|
||||
..Validation::default()
|
||||
};
|
||||
let res = decode::<Claims>(&token, Key::Hmac(b"secret"), &v);
|
||||
assert!(res.is_err());
|
||||
println!("{:?}", res);
|
||||
//assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_algorithm_enum_from_str() {
|
||||
assert!(Algorithm::from_str("HS256").is_ok());
|
||||
assert!(Algorithm::from_str("HS384").is_ok());
|
||||
assert!(Algorithm::from_str("HS512").is_ok());
|
||||
assert!(Algorithm::from_str("RS256").is_ok());
|
||||
assert!(Algorithm::from_str("RS384").is_ok());
|
||||
assert!(Algorithm::from_str("RS512").is_ok());
|
||||
assert!(Algorithm::from_str("PS256").is_ok());
|
||||
assert!(Algorithm::from_str("PS384").is_ok());
|
||||
assert!(Algorithm::from_str("PS512").is_ok());
|
||||
assert!(Algorithm::from_str("").is_err());
|
||||
}
|
||||
mod ec;
|
||||
mod rsa;
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
extern crate jsonwebtoken;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate chrono;
|
||||
|
||||
use chrono::Utc;
|
||||
use jsonwebtoken::{decode, decode_pem, encode, sign, verify, Algorithm, Header, Key, Validation};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
const RSA_ALGORITHMS: &[Algorithm] = &[
|
||||
Algorithm::RS256,
|
||||
|
@ -126,3 +122,10 @@ fn rsa_modulus_exponent() {
|
|||
.unwrap();
|
||||
assert!(is_valid);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidKeyFormat")]
|
||||
fn fails_with_non_pkcs8_key_format() {
|
||||
let privkey = include_bytes!("private_rsa_key.der");
|
||||
let _encrypted = sign("hello world", Key::Der(&privkey[..]), Algorithm::ES256).unwrap();
|
||||
}
|
Loading…
Reference in New Issue