Holy moley... all the Optional Json fields needed #[serde(default)] on them. Talk about boilerplate...
This commit is contained in:
parent
50de2dacb3
commit
3e71047f42
158
src/discovery.rs
158
src/discovery.rs
|
@ -4,7 +4,6 @@ use inth_oauth2::provider::Provider;
|
||||||
use inth_oauth2::token::Expiring;
|
use inth_oauth2::token::Expiring;
|
||||||
use reqwest::{Client, Url};
|
use reqwest::{Client, Url};
|
||||||
use url_serde;
|
use url_serde;
|
||||||
use validator::Validate;
|
|
||||||
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
@ -17,104 +16,63 @@ pub(crate) fn secure(url: &Url) -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[serde(with = "url_serde")]
|
#[serde(with = "url_serde")] pub issuer: Url,
|
||||||
pub issuer: Url,
|
#[serde(with = "url_serde")] pub authorization_endpoint: Url,
|
||||||
#[serde(with = "url_serde")]
|
|
||||||
pub authorization_endpoint: Url,
|
|
||||||
#[serde(with = "url_serde")]
|
|
||||||
// Only optional in the implicit flow
|
// Only optional in the implicit flow
|
||||||
// TODO For now, we only support code flows.
|
// TODO For now, we only support code flows.
|
||||||
pub token_endpoint: Url,
|
#[serde(with = "url_serde")] pub token_endpoint: Url,
|
||||||
#[serde(with = "url_serde")]
|
#[serde(default)] #[serde(with = "url_serde")] pub userinfo_endpoint: Option<Url>,
|
||||||
pub userinfo_endpoint: Option<Url>,
|
#[serde(with = "url_serde")] pub jwks_uri: Url,
|
||||||
#[serde(with = "url_serde")]
|
#[serde(default)] #[serde(with = "url_serde")] pub registration_endpoint: Option<Url>,
|
||||||
pub jwks_uri: Url,
|
#[serde(default)] pub scopes_supported: Option<Vec<String>>,
|
||||||
#[serde(with = "url_serde")]
|
|
||||||
pub registration_endpoint: Option<Url>,
|
|
||||||
pub scopes_supported: Option<Vec<String>>,
|
|
||||||
// There are only three valid response types, plus combinations of them, and none
|
// There are only three valid response types, plus combinations of them, and none
|
||||||
// If we want to make these user friendly we want a struct to represent all 7 types
|
// If we want to make these user friendly we want a struct to represent all 7 types
|
||||||
pub response_types_supported: Vec<String>,
|
pub response_types_supported: Vec<String>,
|
||||||
// There are only two possible values here, query and fragment. Default is both.
|
// There are only two possible values here, query and fragment. Default is both.
|
||||||
pub response_modes_supported: Option<Vec<String>>,
|
#[serde(default)] pub response_modes_supported: Option<Vec<String>>,
|
||||||
// Must support at least authorization_code and implicit.
|
// Must support at least authorization_code and implicit.
|
||||||
pub grant_types_supported: Option<Vec<String>>,
|
#[serde(default)] pub grant_types_supported: Option<Vec<String>>,
|
||||||
pub acr_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub acr_values_supported: Option<Vec<String>>,
|
||||||
// pairwise and public are valid by spec, but servers can add more
|
// pairwise and public are valid by spec, but servers can add more
|
||||||
pub subject_types_supported: Vec<String>,
|
pub subject_types_supported: Vec<String>,
|
||||||
// Must include at least RS256, none is only allowed with response types without id tokens
|
// Must include at least RS256, none is only allowed with response types without id tokens
|
||||||
pub id_token_signing_alg_values_supported: Vec<String>,
|
pub id_token_signing_alg_values_supported: Vec<String>,
|
||||||
pub id_token_encryption_alg_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub id_token_encryption_alg_values_supported: Option<Vec<String>>,
|
||||||
pub id_token_encryption_enc_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub id_token_encryption_enc_values_supported: Option<Vec<String>>,
|
||||||
pub userinfo_signing_alg_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub userinfo_signing_alg_values_supported: Option<Vec<String>>,
|
||||||
pub userinfo_encryption_alg_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub userinfo_encryption_alg_values_supported: Option<Vec<String>>,
|
||||||
pub userinfo_encryption_enc_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub userinfo_encryption_enc_values_supported: Option<Vec<String>>,
|
||||||
pub request_object_signing_alg_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub request_object_signing_alg_values_supported: Option<Vec<String>>,
|
||||||
pub request_object_encryption_alg_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub request_object_encryption_alg_values_supported: Option<Vec<String>>,
|
||||||
pub request_object_encryption_enc_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub request_object_encryption_enc_values_supported: Option<Vec<String>>,
|
||||||
// Spec options are client_secret_post, client_secret_basic, client_secret_jwt, private_key_jwt
|
// Spec options are client_secret_post, client_secret_basic, client_secret_jwt, private_key_jwt
|
||||||
// If omitted, client_secret_basic is used
|
// If omitted, client_secret_basic is used
|
||||||
pub token_endpoint_auth_methods_supported: Option<Vec<String>>,
|
#[serde(default)] pub token_endpoint_auth_methods_supported: Option<Vec<String>>,
|
||||||
// Only wanted with jwt auth methods, should have RS256, none not allowed
|
// Only wanted with jwt auth methods, should have RS256, none not allowed
|
||||||
pub token_endpoint_auth_signing_alg_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub token_endpoint_auth_signing_alg_values_supported: Option<Vec<String>>,
|
||||||
pub display_values_supported: Option<Vec<String>>,
|
#[serde(default)] pub display_values_supported: Option<Vec<String>>,
|
||||||
// Valid options are normal, aggregated, and distributed. If omitted, only use normal
|
// Valid options are normal, aggregated, and distributed. If omitted, only use normal
|
||||||
pub claim_types_supported: Option<Vec<String>>,
|
#[serde(default)] pub claim_types_supported: Option<Vec<String>>,
|
||||||
pub claims_supported: Option<Vec<Claim>>,
|
#[serde(default)] pub claims_supported: Option<Vec<String>>,
|
||||||
#[serde(with = "url_serde")]
|
#[serde(default)] #[serde(with = "url_serde")] pub service_documentation: Option<Url>,
|
||||||
pub service_documentation: Option<Url>,
|
#[serde(default)] pub claims_locales_supported: Option<Vec<String>>,
|
||||||
pub claims_locales_supported: Option<Vec<String>>,
|
#[serde(default)] pub ui_locales_supported: Option<Vec<String>>,
|
||||||
pub ui_locales_supported: Option<Vec<String>>,
|
#[serde(default)] pub claims_parameter_supported: bool,
|
||||||
// default false
|
#[serde(default)] pub request_parameter_supported: bool,
|
||||||
pub claims_parameter_supported: Option<bool>,
|
#[serde(default = "tru")] pub request_uri_parameter_supported: bool,
|
||||||
// default false
|
#[serde(default)] pub require_request_uri_registration: bool,
|
||||||
pub request_parameter_supported: Option<bool>,
|
|
||||||
// default true
|
#[serde(default)] #[serde(with = "url_serde")] pub op_policy_uri: Option<Url>,
|
||||||
pub request_uri_parameter_supported: Option<bool>,
|
#[serde(default)] #[serde(with = "url_serde")] pub op_tos_uri: Option<Url>,
|
||||||
// default false
|
|
||||||
pub require_request_uri_registration: Option<bool>,
|
|
||||||
#[serde(with = "url_serde")]
|
|
||||||
pub op_policy_uri: Option<Url>,
|
|
||||||
#[serde(with = "url_serde")]
|
|
||||||
pub op_tos_uri: Option<Url>,
|
|
||||||
// This is a NONSTANDARD extension Google uses that is a part of the Oauth discovery draft
|
// This is a NONSTANDARD extension Google uses that is a part of the Oauth discovery draft
|
||||||
pub code_challenge_methods_supported: Option<Vec<String>>,
|
#[serde(default)] pub code_challenge_methods_supported: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
// This seems really dumb...
|
||||||
pub enum Claim {
|
fn tru() -> bool {
|
||||||
Name(String),
|
true
|
||||||
FamilyName(String),
|
|
||||||
GivenName(String),
|
|
||||||
MiddleName(String),
|
|
||||||
Nickname(String),
|
|
||||||
PreferredUsername(String),
|
|
||||||
Profile(
|
|
||||||
#[serde(with = "url_serde")]
|
|
||||||
Url
|
|
||||||
),
|
|
||||||
Picture(
|
|
||||||
#[serde(with = "url_serde")]
|
|
||||||
Url
|
|
||||||
),
|
|
||||||
Website(
|
|
||||||
#[serde(with = "url_serde")]
|
|
||||||
Url
|
|
||||||
),
|
|
||||||
Gender(String),
|
|
||||||
Birthdate(String),
|
|
||||||
Zoneinfo(String),
|
|
||||||
Locale(String),
|
|
||||||
UpdatedAt(u64),
|
|
||||||
Email(Email),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Validate)]
|
|
||||||
pub struct Email {
|
|
||||||
#[validate(email)]
|
|
||||||
pub address: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Discovered {
|
pub struct Discovered {
|
||||||
|
@ -137,7 +95,8 @@ impl Provider for Discovered {
|
||||||
/// or an Insecure if the Url isn't https.
|
/// or an Insecure if the Url isn't https.
|
||||||
pub fn discover(client: &Client, issuer: Url) -> Result<Config, Error> {
|
pub fn discover(client: &Client, issuer: Url) -> Result<Config, Error> {
|
||||||
secure(&issuer)?;
|
secure(&issuer)?;
|
||||||
let mut resp = client.get(issuer)?.send()?;
|
let url = issuer.join("/.well-known/openid-configuration")?;
|
||||||
|
let mut resp = client.get(url)?.send()?;
|
||||||
resp.json().map_err(Error::from)
|
resp.json().map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,3 +107,40 @@ pub fn jwks(client: &Client, url: Url) -> Result<JWKSet<Empty>, Error> {
|
||||||
let mut resp = client.get(url)?.send()?;
|
let mut resp = client.get(url)?.send()?;
|
||||||
resp.json().map_err(Error::from)
|
resp.json().map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn config_google() {
|
||||||
|
let cfg = r#"{ "issuer": "https://accounts.google.com",
|
||||||
|
"authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
|
||||||
|
"token_endpoint": "https://www.googleapis.com/oauth2/v4/token",
|
||||||
|
"userinfo_endpoint": "https://www.googleapis.com/oauth2/v3/userinfo",
|
||||||
|
"revocation_endpoint": "https://accounts.google.com/o/oauth2/revoke",
|
||||||
|
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
|
||||||
|
"response_types_supported": [ "code", "token", "id_token", "code token",
|
||||||
|
"code id_token", "token id_token",
|
||||||
|
"code token id_token", "none" ],
|
||||||
|
"subject_types_supported": [ "public" ],
|
||||||
|
"id_token_signing_alg_values_supported": [ "RS256" ],
|
||||||
|
"scopes_supported": [ "openid", "email", "profile" ],
|
||||||
|
"token_endpoint_auth_methods_supported": [ "client_secret_post",
|
||||||
|
"client_secret_basic" ],
|
||||||
|
"claims_supported": [ "aud", "email", "email_verified", "exp", "family_name",
|
||||||
|
"given_name", "iat", "iss", "locale", "name", "picture",
|
||||||
|
"sub" ],
|
||||||
|
"code_challenge_methods_supported": [ "plain", "S256" ]
|
||||||
|
}"#;
|
||||||
|
println!("{:?}", ::serde_json::from_str::<Config>(cfg).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn config_minimum() {
|
||||||
|
let cfg = r#"{ "issuer": "https://example.com",
|
||||||
|
"authorization_endpoint": "https://example.com/auth",
|
||||||
|
"token_endpoint": "https://example.com/token",
|
||||||
|
"jwks_uri": "https://example.com/certs",
|
||||||
|
"response_types_supported": [ "code" ],
|
||||||
|
"subject_types_supported": [ "public" ],
|
||||||
|
"id_token_signing_alg_values_supported": [ "RS256" ]
|
||||||
|
}"#;
|
||||||
|
println!("{:?}", ::serde_json::from_str::<Config>(cfg).unwrap());
|
||||||
|
}
|
||||||
|
|
28
src/error.rs
28
src/error.rs
|
@ -2,6 +2,7 @@ pub use biscuit::errors::Error as Jose;
|
||||||
pub use serde_json::Error as Json;
|
pub use serde_json::Error as Json;
|
||||||
pub use inth_oauth2::ClientError as Oauth;
|
pub use inth_oauth2::ClientError as Oauth;
|
||||||
pub use reqwest::Error as Reqwest;
|
pub use reqwest::Error as Reqwest;
|
||||||
|
pub use reqwest::UrlError as Url;
|
||||||
|
|
||||||
use std::fmt::{Display, Formatter, Result};
|
use std::fmt::{Display, Formatter, Result};
|
||||||
use std::error::Error as ErrorTrait;
|
use std::error::Error as ErrorTrait;
|
||||||
|
@ -22,6 +23,7 @@ pub enum Error {
|
||||||
Json(Json),
|
Json(Json),
|
||||||
Oauth(Oauth),
|
Oauth(Oauth),
|
||||||
Reqwest(Reqwest),
|
Reqwest(Reqwest),
|
||||||
|
Url(Url),
|
||||||
Decode(Decode),
|
Decode(Decode),
|
||||||
Validation(Validation),
|
Validation(Validation),
|
||||||
Userinfo(Userinfo),
|
Userinfo(Userinfo),
|
||||||
|
@ -33,6 +35,7 @@ from!(Error, Jose);
|
||||||
from!(Error, Json);
|
from!(Error, Json);
|
||||||
from!(Error, Oauth);
|
from!(Error, Oauth);
|
||||||
from!(Error, Reqwest);
|
from!(Error, Reqwest);
|
||||||
|
from!(Error, Url);
|
||||||
from!(Error, Decode);
|
from!(Error, Decode);
|
||||||
from!(Error, Validation);
|
from!(Error, Validation);
|
||||||
from!(Error, Userinfo);
|
from!(Error, Userinfo);
|
||||||
|
@ -45,6 +48,7 @@ impl Display for Error {
|
||||||
Json(ref err) => Display::fmt(err, f),
|
Json(ref err) => Display::fmt(err, f),
|
||||||
Oauth(ref err) => Display::fmt(err, f),
|
Oauth(ref err) => Display::fmt(err, f),
|
||||||
Reqwest(ref err) => Display::fmt(err, f),
|
Reqwest(ref err) => Display::fmt(err, f),
|
||||||
|
Url(ref err) => Display::fmt(err, f),
|
||||||
Decode(ref err) => Display::fmt(err, f),
|
Decode(ref err) => Display::fmt(err, f),
|
||||||
Validation(ref err) => Display::fmt(err, f),
|
Validation(ref err) => Display::fmt(err, f),
|
||||||
Userinfo(ref err) => Display::fmt(err, f),
|
Userinfo(ref err) => Display::fmt(err, f),
|
||||||
|
@ -62,6 +66,7 @@ impl ErrorTrait for Error {
|
||||||
Json(ref err) => err.description(),
|
Json(ref err) => err.description(),
|
||||||
Oauth(ref err) => err.description(),
|
Oauth(ref err) => err.description(),
|
||||||
Reqwest(ref err) => err.description(),
|
Reqwest(ref err) => err.description(),
|
||||||
|
Url(ref err) => err.description(),
|
||||||
Decode(ref err) => err.description(),
|
Decode(ref err) => err.description(),
|
||||||
Validation(ref err) => err.description(),
|
Validation(ref err) => err.description(),
|
||||||
Userinfo(ref err) => err.description(),
|
Userinfo(ref err) => err.description(),
|
||||||
|
@ -77,9 +82,10 @@ impl ErrorTrait for Error {
|
||||||
Json(ref err) => Some(err),
|
Json(ref err) => Some(err),
|
||||||
Oauth(ref err) => Some(err),
|
Oauth(ref err) => Some(err),
|
||||||
Reqwest(ref err) => Some(err),
|
Reqwest(ref err) => Some(err),
|
||||||
Decode(ref err) => None,
|
Url(ref err) => Some(err),
|
||||||
Validation(ref err) => None,
|
Decode(_) => None,
|
||||||
Userinfo(ref err) => None,
|
Validation(_) => None,
|
||||||
|
Userinfo(_) => None,
|
||||||
Insecure(_) => None,
|
Insecure(_) => None,
|
||||||
MissingOpenidScope => None,
|
MissingOpenidScope => None,
|
||||||
}
|
}
|
||||||
|
@ -95,9 +101,10 @@ pub enum Decode {
|
||||||
|
|
||||||
impl ErrorTrait for Decode {
|
impl ErrorTrait for Decode {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match self {
|
use Decode::*;
|
||||||
|
match *self {
|
||||||
MissingKid => "Missing Key Id",
|
MissingKid => "Missing Key Id",
|
||||||
&Decode::MissingKey(_) => "Token key not in key set",
|
MissingKey(_) => "Token key not in key set",
|
||||||
EmptySet => "JWK Set is empty",
|
EmptySet => "JWK Set is empty",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,9 +115,10 @@ impl ErrorTrait for Decode {
|
||||||
|
|
||||||
impl Display for Decode {
|
impl Display for Decode {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||||
match self {
|
use Decode::*;
|
||||||
|
match *self {
|
||||||
MissingKid => write!(f, "Token Missing Key Id when key set has multiple keys"),
|
MissingKid => write!(f, "Token Missing Key Id when key set has multiple keys"),
|
||||||
&Decode::MissingKey(ref id) =>
|
MissingKey(ref id) =>
|
||||||
write!(f, "Token wants this key id not in the key set: {}", id),
|
write!(f, "Token wants this key id not in the key set: {}", id),
|
||||||
EmptySet => write!(f, "JWK Set is empty!")
|
EmptySet => write!(f, "JWK Set is empty!")
|
||||||
}
|
}
|
||||||
|
@ -137,7 +145,8 @@ impl ErrorTrait for Validation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Missing(ref mi) => {
|
Missing(ref mi) => {
|
||||||
match mi {
|
use Missing::*;
|
||||||
|
match *mi {
|
||||||
Audience => "Token missing Audience",
|
Audience => "Token missing Audience",
|
||||||
AuthorizedParty => "Token missing AZP",
|
AuthorizedParty => "Token missing AZP",
|
||||||
AuthTime => "Token missing Auth Time",
|
AuthTime => "Token missing Auth Time",
|
||||||
|
@ -200,7 +209,8 @@ pub enum Missing {
|
||||||
|
|
||||||
impl Display for Missing {
|
impl Display for Missing {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||||
match self {
|
use Missing::*;
|
||||||
|
match *self {
|
||||||
Audience => write!(f, "Token missing Audience"),
|
Audience => write!(f, "Token missing Audience"),
|
||||||
AuthorizedParty => write!(f, "Token missing AZP"),
|
AuthorizedParty => write!(f, "Token missing AZP"),
|
||||||
AuthTime => write!(f, "Token missing Auth Time"),
|
AuthTime => write!(f, "Token missing Auth Time"),
|
||||||
|
|
|
@ -13,3 +13,9 @@ pub fn paypal() -> Url {
|
||||||
pub fn salesforce() -> Url {
|
pub fn salesforce() -> Url {
|
||||||
Url::parse("http://login.salesforce.com").unwrap()
|
Url::parse("http://login.salesforce.com").unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn google_disco() {
|
||||||
|
let client = ::reqwest::Client::new().unwrap();
|
||||||
|
let config = ::discovery::discover(&client, google()).unwrap();
|
||||||
|
}
|
20
src/lib.rs
20
src/lib.rs
|
@ -425,7 +425,8 @@ pub enum Display {
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
fn as_str(&self) -> &'static str {
|
fn as_str(&self) -> &'static str {
|
||||||
match self {
|
use Display::*;
|
||||||
|
match *self {
|
||||||
Page => "page",
|
Page => "page",
|
||||||
Popup => "popup",
|
Popup => "popup",
|
||||||
Touch => "touch",
|
Touch => "touch",
|
||||||
|
@ -444,8 +445,9 @@ pub enum Prompt {
|
||||||
|
|
||||||
impl Prompt {
|
impl Prompt {
|
||||||
fn as_str(&self) -> &'static str {
|
fn as_str(&self) -> &'static str {
|
||||||
match self {
|
use Prompt::*;
|
||||||
&Prompt::None => "none",
|
match *self {
|
||||||
|
None => "none",
|
||||||
Login => "login",
|
Login => "login",
|
||||||
Consent => "consent",
|
Consent => "consent",
|
||||||
SelectAccount => "select_account",
|
SelectAccount => "select_account",
|
||||||
|
@ -456,11 +458,11 @@ impl Prompt {
|
||||||
/// Address Claim struct. Can be only formatted, only the rest, or both.
|
/// Address Claim struct. Can be only formatted, only the rest, or both.
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Address {
|
pub struct Address {
|
||||||
pub formatted: Option<String>,
|
#[serde(default)] pub formatted: Option<String>,
|
||||||
pub street_address: Option<String>,
|
#[serde(default)] pub street_address: Option<String>,
|
||||||
pub locality: Option<String>,
|
#[serde(default)] pub locality: Option<String>,
|
||||||
pub region: Option<String>,
|
#[serde(default)] pub region: Option<String>,
|
||||||
// Countries like the UK use alphanumeric postal codes, so you can't just use a number here
|
// Countries like the UK use alphanumeric postal codes, so you can't just use a number here
|
||||||
pub postal_code: Option<String>,
|
#[serde(default)] pub postal_code: Option<String>,
|
||||||
pub country: Option<String>,
|
#[serde(default)] pub country: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
15
src/token.rs
15
src/token.rs
|
@ -11,8 +11,7 @@ type IdToken = Compact<Claims, Empty>;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Claims {
|
pub struct Claims {
|
||||||
#[serde(with = "url_serde")]
|
#[serde(with = "url_serde")] pub iss: Url,
|
||||||
pub iss: Url,
|
|
||||||
// Max 255 ASCII chars
|
// Max 255 ASCII chars
|
||||||
// Can't deserialize a [u8; 255]
|
// Can't deserialize a [u8; 255]
|
||||||
pub sub: String,
|
pub sub: String,
|
||||||
|
@ -27,14 +26,14 @@ pub struct Claims {
|
||||||
pub exp: i64,
|
pub exp: i64,
|
||||||
pub iat: i64,
|
pub iat: i64,
|
||||||
// required for max_age request
|
// required for max_age request
|
||||||
pub auth_time: Option<i64>,
|
#[serde(default)] pub auth_time: Option<i64>,
|
||||||
pub nonce: Option<String>,
|
#[serde(default)] pub nonce: Option<String>,
|
||||||
// base64 encoded, need to decode it!
|
// base64 encoded, need to decode it!
|
||||||
at_hash: Option<String>,
|
#[serde(default)] at_hash: Option<String>,
|
||||||
pub acr: Option<String>,
|
#[serde(default)] pub acr: Option<String>,
|
||||||
pub amr: Option<Vec<String>>,
|
#[serde(default)] pub amr: Option<Vec<String>>,
|
||||||
// If exists, must be client_id
|
// If exists, must be client_id
|
||||||
pub azp: Option<String>,
|
#[serde(default)] pub azp: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Claims {
|
impl Claims {
|
||||||
|
|
Loading…
Reference in New Issue