2019-11-11 13:47:35 -05:00
|
|
|
use std::collections::HashSet;
|
2019-11-11 14:29:57 -05:00
|
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
2019-11-11 13:47:35 -05:00
|
|
|
|
2017-04-11 01:41:44 -04:00
|
|
|
use serde_json::map::Map;
|
2019-10-28 11:49:02 -04:00
|
|
|
use serde_json::{from_value, Value};
|
2017-04-11 01:41:44 -04:00
|
|
|
|
2019-10-31 14:12:08 -04:00
|
|
|
use crate::algorithms::Algorithm;
|
|
|
|
use crate::errors::{new_error, ErrorKind, Result};
|
2017-04-11 01:41:44 -04:00
|
|
|
|
2019-11-14 13:43:43 -05:00
|
|
|
/// Contains the various validations that are applied after decoding a JWT.
|
2017-04-12 21:08:07 -04:00
|
|
|
///
|
2019-11-11 13:47:35 -05:00
|
|
|
/// All time validation happen on UTC timestamps as seconds.
|
2017-06-13 04:51:10 -04:00
|
|
|
///
|
2017-04-12 21:08:07 -04:00
|
|
|
/// ```rust
|
|
|
|
/// use jsonwebtoken::Validation;
|
|
|
|
///
|
|
|
|
/// // Default value
|
|
|
|
/// let validation = Validation::default();
|
2017-06-13 04:51:10 -04:00
|
|
|
///
|
2017-04-12 21:08:07 -04:00
|
|
|
/// // Changing one parameter
|
2017-08-30 05:09:57 -04:00
|
|
|
/// let mut validation = Validation {leeway: 60, ..Default::default()};
|
2017-06-13 04:51:10 -04:00
|
|
|
///
|
2017-04-12 21:08:07 -04:00
|
|
|
/// // Setting audience
|
|
|
|
/// let mut validation = Validation::default();
|
2019-10-28 11:49:02 -04:00
|
|
|
/// validation.set_audience(&["Me"]); // a single string
|
2017-04-12 21:08:07 -04:00
|
|
|
/// validation.set_audience(&["Me", "You"]); // array of strings
|
|
|
|
/// ```
|
2017-04-11 01:41:44 -04:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
pub struct Validation {
|
2017-08-30 05:09:57 -04:00
|
|
|
/// Add some leeway (in seconds) to the `exp`, `iat` and `nbf` validation to
|
2017-04-12 21:08:07 -04:00
|
|
|
/// account for clock skew.
|
|
|
|
///
|
|
|
|
/// Defaults to `0`.
|
2019-11-11 13:47:35 -05:00
|
|
|
pub leeway: u64,
|
2017-04-12 21:08:07 -04:00
|
|
|
/// Whether to validate the `exp` field.
|
|
|
|
///
|
|
|
|
/// It will return an error if the time in the `exp` field is past.
|
|
|
|
///
|
|
|
|
/// Defaults to `true`.
|
2017-04-11 01:41:44 -04:00
|
|
|
pub validate_exp: bool,
|
2017-04-12 21:08:07 -04:00
|
|
|
/// Whether to validate the `nbf` field.
|
|
|
|
///
|
|
|
|
/// It will return an error if the current timestamp is before the time in the `nbf` field.
|
|
|
|
///
|
2019-01-18 02:31:56 -05:00
|
|
|
/// Defaults to `false`.
|
2017-04-11 01:41:44 -04:00
|
|
|
pub validate_nbf: bool,
|
2019-10-28 11:49:02 -04:00
|
|
|
/// If it contains a value, the validation will check that the `aud` field is a member of the
|
|
|
|
/// audience provided and will error otherwise.
|
2017-04-12 21:08:07 -04:00
|
|
|
///
|
2017-04-22 02:21:16 -04:00
|
|
|
/// Defaults to `None`.
|
2019-10-27 15:14:52 -04:00
|
|
|
pub aud: Option<HashSet<String>>,
|
2017-04-12 21:08:07 -04:00
|
|
|
/// If it contains a value, the validation will check that the `iss` field is the same as the
|
|
|
|
/// one provided and will error otherwise.
|
|
|
|
///
|
2017-04-22 02:21:16 -04:00
|
|
|
/// Defaults to `None`.
|
2017-04-11 01:41:44 -04:00
|
|
|
pub iss: Option<String>,
|
2017-04-12 21:08:07 -04:00
|
|
|
/// If it contains a value, the validation will check that the `sub` field is the same as the
|
|
|
|
/// one provided and will error otherwise.
|
|
|
|
///
|
2017-04-22 02:21:16 -04:00
|
|
|
/// Defaults to `None`.
|
2017-04-11 01:41:44 -04:00
|
|
|
pub sub: Option<String>,
|
2017-10-22 07:20:01 -04:00
|
|
|
/// If it contains a value, the validation will check that the `alg` of the header is contained
|
2017-04-22 02:21:16 -04:00
|
|
|
/// in the ones provided and will error otherwise.
|
|
|
|
///
|
2017-10-22 07:20:01 -04:00
|
|
|
/// Defaults to `vec![Algorithm::HS256]`.
|
|
|
|
pub algorithms: Vec<Algorithm>,
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Validation {
|
2017-10-22 07:20:01 -04:00
|
|
|
/// Create a default validation setup allowing the given alg
|
|
|
|
pub fn new(alg: Algorithm) -> Validation {
|
|
|
|
let mut validation = Validation::default();
|
|
|
|
validation.algorithms = vec![alg];
|
|
|
|
validation
|
|
|
|
}
|
|
|
|
|
2019-10-28 11:49:02 -04:00
|
|
|
/// `aud` is a collection of one or more acceptable audience members
|
|
|
|
pub fn set_audience<T: ToString>(&mut self, items: &[T]) {
|
|
|
|
self.aud = Some(items.iter().map(|x| x.to_string()).collect())
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Validation {
|
|
|
|
fn default() -> Validation {
|
|
|
|
Validation {
|
|
|
|
leeway: 0,
|
|
|
|
|
|
|
|
validate_exp: true,
|
2018-07-25 09:42:00 -04:00
|
|
|
validate_nbf: false,
|
2017-04-11 01:41:44 -04:00
|
|
|
|
|
|
|
iss: None,
|
|
|
|
sub: None,
|
|
|
|
aud: None,
|
2017-04-22 02:21:16 -04:00
|
|
|
|
2017-10-22 07:20:01 -04:00
|
|
|
algorithms: vec![Algorithm::HS256],
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-11 13:47:35 -05:00
|
|
|
fn get_current_timestamp() -> u64 {
|
|
|
|
let start = SystemTime::now();
|
|
|
|
start.duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs()
|
|
|
|
}
|
|
|
|
|
2017-04-11 01:41:44 -04:00
|
|
|
pub fn validate(claims: &Map<String, Value>, options: &Validation) -> Result<()> {
|
2019-11-11 13:47:35 -05:00
|
|
|
let now = get_current_timestamp();
|
2017-04-11 01:41:44 -04:00
|
|
|
|
2018-07-25 09:42:00 -04:00
|
|
|
if options.validate_exp {
|
|
|
|
if let Some(exp) = claims.get("exp") {
|
2019-11-11 13:47:35 -05:00
|
|
|
if from_value::<u64>(exp.clone())? < now - options.leeway {
|
2018-07-25 09:42:00 -04:00
|
|
|
return Err(new_error(ErrorKind::ExpiredSignature));
|
|
|
|
}
|
|
|
|
} else {
|
2018-07-25 08:43:58 -04:00
|
|
|
return Err(new_error(ErrorKind::ExpiredSignature));
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-25 09:42:00 -04:00
|
|
|
if options.validate_nbf {
|
|
|
|
if let Some(nbf) = claims.get("nbf") {
|
2019-11-11 13:47:35 -05:00
|
|
|
if from_value::<u64>(nbf.clone())? > now + options.leeway {
|
2018-07-25 09:42:00 -04:00
|
|
|
return Err(new_error(ErrorKind::ImmatureSignature));
|
|
|
|
}
|
|
|
|
} else {
|
2018-07-25 08:43:58 -04:00
|
|
|
return Err(new_error(ErrorKind::ImmatureSignature));
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-25 09:42:00 -04:00
|
|
|
if let Some(ref correct_iss) = options.iss {
|
|
|
|
if let Some(iss) = claims.get("iss") {
|
2017-04-11 01:41:44 -04:00
|
|
|
if from_value::<String>(iss.clone())? != *correct_iss {
|
2018-07-25 08:43:58 -04:00
|
|
|
return Err(new_error(ErrorKind::InvalidIssuer));
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
2018-07-25 09:42:00 -04:00
|
|
|
} else {
|
|
|
|
return Err(new_error(ErrorKind::InvalidIssuer));
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-25 09:42:00 -04:00
|
|
|
if let Some(ref correct_sub) = options.sub {
|
|
|
|
if let Some(sub) = claims.get("sub") {
|
2017-04-11 01:41:44 -04:00
|
|
|
if from_value::<String>(sub.clone())? != *correct_sub {
|
2018-07-25 08:43:58 -04:00
|
|
|
return Err(new_error(ErrorKind::InvalidSubject));
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
2018-07-25 09:42:00 -04:00
|
|
|
} else {
|
|
|
|
return Err(new_error(ErrorKind::InvalidSubject));
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-25 09:42:00 -04:00
|
|
|
if let Some(ref correct_aud) = options.aud {
|
|
|
|
if let Some(aud) = claims.get("aud") {
|
2019-11-03 07:55:36 -05:00
|
|
|
let provided_aud: HashSet<String> = from_value(aud.clone())?;
|
|
|
|
if provided_aud.intersection(correct_aud).count() == 0 {
|
2018-07-25 08:43:58 -04:00
|
|
|
return Err(new_error(ErrorKind::InvalidAudience));
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
2018-07-25 09:42:00 -04:00
|
|
|
} else {
|
|
|
|
return Err(new_error(ErrorKind::InvalidAudience));
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2018-10-28 14:58:35 -04:00
|
|
|
use serde_json::map::Map;
|
|
|
|
use serde_json::to_value;
|
2017-04-11 01:41:44 -04:00
|
|
|
|
2019-11-11 14:29:57 -05:00
|
|
|
use super::{get_current_timestamp, validate, Validation};
|
2017-04-11 01:41:44 -04:00
|
|
|
|
2019-10-31 14:12:08 -04:00
|
|
|
use crate::errors::ErrorKind;
|
2017-04-11 01:41:44 -04:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn exp_in_future_ok() {
|
|
|
|
let mut claims = Map::new();
|
2019-11-11 13:47:35 -05:00
|
|
|
claims.insert("exp".to_string(), to_value(get_current_timestamp() + 10000).unwrap());
|
2017-04-11 01:41:44 -04:00
|
|
|
let res = validate(&claims, &Validation::default());
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn exp_in_past_fails() {
|
|
|
|
let mut claims = Map::new();
|
2019-11-11 13:47:35 -05:00
|
|
|
claims.insert("exp".to_string(), to_value(get_current_timestamp() - 100000).unwrap());
|
2017-04-11 01:41:44 -04:00
|
|
|
let res = validate(&claims, &Validation::default());
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::ExpiredSignature => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn exp_in_past_but_in_leeway_ok() {
|
|
|
|
let mut claims = Map::new();
|
2019-11-11 13:47:35 -05:00
|
|
|
claims.insert("exp".to_string(), to_value(get_current_timestamp() - 500).unwrap());
|
2018-10-28 14:58:35 -04:00
|
|
|
let validation = Validation { leeway: 1000 * 60, ..Default::default() };
|
2017-04-11 01:41:44 -04:00
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
|
|
|
|
2018-07-25 09:42:00 -04:00
|
|
|
// https://github.com/Keats/jsonwebtoken/issues/51
|
|
|
|
#[test]
|
|
|
|
fn validation_called_even_if_field_is_empty() {
|
|
|
|
let claims = Map::new();
|
|
|
|
let res = validate(&claims, &Validation::default());
|
|
|
|
assert!(res.is_err());
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::ExpiredSignature => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-04-11 01:41:44 -04:00
|
|
|
#[test]
|
|
|
|
fn nbf_in_past_ok() {
|
|
|
|
let mut claims = Map::new();
|
2019-11-11 13:47:35 -05:00
|
|
|
claims.insert("nbf".to_string(), to_value(get_current_timestamp() - 10000).unwrap());
|
2018-10-28 14:58:35 -04:00
|
|
|
let validation =
|
|
|
|
Validation { validate_exp: false, validate_nbf: true, ..Validation::default() };
|
2018-07-25 09:42:00 -04:00
|
|
|
let res = validate(&claims, &validation);
|
2017-04-11 01:41:44 -04:00
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nbf_in_future_fails() {
|
|
|
|
let mut claims = Map::new();
|
2019-11-11 13:47:35 -05:00
|
|
|
claims.insert("nbf".to_string(), to_value(get_current_timestamp() + 100000).unwrap());
|
2018-10-28 14:58:35 -04:00
|
|
|
let validation =
|
|
|
|
Validation { validate_exp: false, validate_nbf: true, ..Validation::default() };
|
2018-07-25 09:42:00 -04:00
|
|
|
let res = validate(&claims, &validation);
|
2017-04-11 01:41:44 -04:00
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::ImmatureSignature => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nbf_in_future_but_in_leeway_ok() {
|
|
|
|
let mut claims = Map::new();
|
2019-11-11 13:47:35 -05:00
|
|
|
claims.insert("nbf".to_string(), to_value(get_current_timestamp() + 500).unwrap());
|
2017-04-11 01:41:44 -04:00
|
|
|
let validation = Validation {
|
|
|
|
leeway: 1000 * 60,
|
2018-07-25 09:42:00 -04:00
|
|
|
validate_nbf: true,
|
|
|
|
validate_exp: false,
|
2017-04-11 01:41:44 -04:00
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn iss_ok() {
|
|
|
|
let mut claims = Map::new();
|
|
|
|
claims.insert("iss".to_string(), to_value("Keats").unwrap());
|
|
|
|
let validation = Validation {
|
2018-07-25 09:42:00 -04:00
|
|
|
validate_exp: false,
|
2017-04-11 01:41:44 -04:00
|
|
|
iss: Some("Keats".to_string()),
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn iss_not_matching_fails() {
|
|
|
|
let mut claims = Map::new();
|
|
|
|
claims.insert("iss".to_string(), to_value("Hacked").unwrap());
|
|
|
|
let validation = Validation {
|
2018-07-25 09:42:00 -04:00
|
|
|
validate_exp: false,
|
|
|
|
iss: Some("Keats".to_string()),
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::InvalidIssuer => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn iss_missing_fails() {
|
|
|
|
let claims = Map::new();
|
|
|
|
let validation = Validation {
|
|
|
|
validate_exp: false,
|
2017-04-11 01:41:44 -04:00
|
|
|
iss: Some("Keats".to_string()),
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::InvalidIssuer => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn sub_ok() {
|
|
|
|
let mut claims = Map::new();
|
|
|
|
claims.insert("sub".to_string(), to_value("Keats").unwrap());
|
|
|
|
let validation = Validation {
|
2018-07-25 09:42:00 -04:00
|
|
|
validate_exp: false,
|
2017-04-11 01:41:44 -04:00
|
|
|
sub: Some("Keats".to_string()),
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn sub_not_matching_fails() {
|
|
|
|
let mut claims = Map::new();
|
|
|
|
claims.insert("sub".to_string(), to_value("Hacked").unwrap());
|
|
|
|
let validation = Validation {
|
2018-07-25 09:42:00 -04:00
|
|
|
validate_exp: false,
|
|
|
|
sub: Some("Keats".to_string()),
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::InvalidSubject => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn sub_missing_fails() {
|
|
|
|
let claims = Map::new();
|
|
|
|
let validation = Validation {
|
|
|
|
validate_exp: false,
|
2017-04-11 01:41:44 -04:00
|
|
|
sub: Some("Keats".to_string()),
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::InvalidSubject => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn aud_string_ok() {
|
|
|
|
let mut claims = Map::new();
|
2019-10-28 11:49:02 -04:00
|
|
|
claims.insert("aud".to_string(), to_value(["Everyone"]).unwrap());
|
2018-10-28 14:58:35 -04:00
|
|
|
let mut validation = Validation { validate_exp: false, ..Validation::default() };
|
2019-10-28 11:49:02 -04:00
|
|
|
validation.set_audience(&["Everyone"]);
|
2017-04-11 01:41:44 -04:00
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn aud_array_of_string_ok() {
|
|
|
|
let mut claims = Map::new();
|
|
|
|
claims.insert("aud".to_string(), to_value(["UserA", "UserB"]).unwrap());
|
2018-10-28 14:58:35 -04:00
|
|
|
let mut validation = Validation { validate_exp: false, ..Validation::default() };
|
2017-04-11 01:41:44 -04:00
|
|
|
validation.set_audience(&["UserA", "UserB"]);
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn aud_type_mismatch_fails() {
|
|
|
|
let mut claims = Map::new();
|
2019-10-28 11:49:02 -04:00
|
|
|
claims.insert("aud".to_string(), to_value(["Everyone"]).unwrap());
|
2018-10-28 14:58:35 -04:00
|
|
|
let mut validation = Validation { validate_exp: false, ..Validation::default() };
|
2017-04-11 01:41:44 -04:00
|
|
|
validation.set_audience(&["UserA", "UserB"]);
|
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::InvalidAudience => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn aud_correct_type_not_matching_fails() {
|
|
|
|
let mut claims = Map::new();
|
2019-10-28 11:49:02 -04:00
|
|
|
claims.insert("aud".to_string(), to_value(["Everyone"]).unwrap());
|
2018-10-28 14:58:35 -04:00
|
|
|
let mut validation = Validation { validate_exp: false, ..Validation::default() };
|
2019-10-28 11:49:02 -04:00
|
|
|
validation.set_audience(&["None"]);
|
2018-07-25 09:42:00 -04:00
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::InvalidAudience => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn aud_missing_fails() {
|
|
|
|
let claims = Map::new();
|
2018-10-28 14:58:35 -04:00
|
|
|
let mut validation = Validation { validate_exp: false, ..Validation::default() };
|
2019-10-28 11:49:02 -04:00
|
|
|
validation.set_audience(&["None"]);
|
2017-04-11 01:41:44 -04:00
|
|
|
let res = validate(&claims, &validation);
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
match res.unwrap_err().kind() {
|
|
|
|
&ErrorKind::InvalidAudience => (),
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
}
|
2019-11-03 10:36:19 -05:00
|
|
|
|
|
|
|
// https://github.com/Keats/jsonwebtoken/issues/51
|
|
|
|
#[test]
|
|
|
|
fn does_validation_in_right_order() {
|
|
|
|
let mut claims = Map::new();
|
2019-11-11 13:47:35 -05:00
|
|
|
claims.insert("exp".to_string(), to_value(get_current_timestamp() + 10000).unwrap());
|
2019-11-03 10:36:19 -05:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2017-04-11 01:41:44 -04:00
|
|
|
}
|