1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#![deny(warnings)]
#![warn(unused_extern_crates)]
#![warn(missing_docs)]
#![forbid(unsafe_code)]
// Enable some groups of clippy lints.
#![deny(clippy::suspicious)]
#![deny(clippy::perf)]
// Specific lints to enforce.
#![deny(clippy::todo)]
#![deny(clippy::unimplemented)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::expect_used)]
#![deny(clippy::panic)]
#![deny(clippy::await_holding_lock)]
#![deny(clippy::needless_pass_by_value)]
#![deny(clippy::trivially_copy_pass_by_ref)]
#![deny(clippy::disallowed_types)]
#![deny(clippy::manual_let_else)]
#![allow(clippy::unreachable)]

//! Json Web Tokens (JWT) are a popular method for creating signed transparent tokens that can be verified
//! by clients and servers. They are enshrined in standards like OpenID Connect which causes them to
//! be a widespread and required component of many modern web authentication system.
//!
//! This is a minimal implementation of JWTs and Oidc Tokens that aims for auditability and correctness.
//!
//! # Examples
//! ```
//! # #[cfg(feature = "openssl")]
//! # {
//! use std::str::FromStr;
//! use std::convert::TryFrom;
//! use std::time::SystemTime;
//! use url::Url;
//! use compact_jwt::{
//!     OidcToken,
//!     OidcSubject,
//!     OidcUnverified,
//!     JwsEs256Signer,
//!     // Traits
//!     JwsSigner,
//!     JwsSignerToVerifier,
//!     JwsVerifier,
//! };
//!
//! let oidc = OidcToken {
//!         iss: Url::parse("https://oidc.example.com").unwrap(),
//!         sub: OidcSubject::S("UniqueId".to_string()),
//! #       aud: "test".to_string(),
//! #       exp: 0,
//! #       nbf: Some(0),
//! #       iat: 0,
//! #       auth_time: Some(0),
//! #       nonce: None,
//! #       at_hash: None,
//! #       acr: None,
//! #       amr: None,
//! #       azp: None,
//! #       jti: None,
//! #       s_claims: Default::default(),
//! #       claims: Default::default(),
//!     };
//!
//! let mut jws_es256_signer =
//!     JwsEs256Signer::generate_es256().unwrap();
//!
//! let oidc_signed = jws_es256_signer.sign(&oidc)
//!     .unwrap();
//!
//! // Get the signed formatted token string
//! let token_str = oidc_signed.to_string();
//!
//! // Build a validator from the public key of the signer. In a client scenario
//! // you would get this public jwk from the oidc authorisation server.
//! let mut jwk_es256_verifier = jws_es256_signer
//!     .get_verifier()
//!     .expect("failed to get verifier from signer");
//!
//! // Assuming we have the token_str, we parse it to an unverified state.
//! let oidc_unverified = OidcUnverified::from_str(&token_str)
//!     .unwrap();
//!
//! let curtime = SystemTime::now()
//!     .duration_since(SystemTime::UNIX_EPOCH)
//!     .expect("Failed to retrieve current time")
//!     .as_secs() as i64;
//!
//! let oidc_validated = jwk_es256_verifier
//!     .verify(&oidc_unverified)
//!     .and_then(|oidc_exp| oidc_exp.verify_exp(curtime))
//!     .unwrap();
//!
//! // Prove we got back the same content.
//! assert!(oidc_validated == oidc);
//! # }
//! ```

#[allow(unused_imports)]
#[macro_use]
extern crate tracing;

#[cfg(feature = "openssl")]
pub mod crypto;

#[cfg(feature = "unsafe_release_without_verify")]
pub mod dangernoverify;

pub mod compact;

pub mod traits;

pub mod error;
pub mod jws;
pub mod jwt;
pub mod oidc;

#[cfg(feature = "openssl")]
pub use crate::crypto::{JwsEs256Signer, JwsEs256Verifier, JwsHs256Signer};

pub use crate::compact::{JwaAlg, Jwk, JwkKeySet, JwkUse, JwsCompact};
pub use crate::error::JwtError;
pub use crate::jws::{Jws, JwsSigned};
pub use crate::jwt::{Jwt, JwtSigned, JwtUnverified};
pub use crate::oidc::{OidcClaims, OidcSigned, OidcSubject, OidcToken, OidcUnverified};

pub use crate::traits::{JwsSigner, JwsSignerToVerifier, JwsVerifier};

pub(crate) fn btreemap_empty(
    m: &std::collections::BTreeMap<String, serde_json::value::Value>,
) -> bool {
    m.is_empty()
}

pub(crate) fn vec_empty(m: &[String]) -> bool {
    m.is_empty()
}