feat: claim types
This commit is contained in:
@@ -53,14 +53,25 @@ impl Command for CommandImpl {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut jwt_claims = Map::new();
|
let mut jwt_claims = Map::new();
|
||||||
|
if let Some(payload) = payload {
|
||||||
|
match serde_json::from_str::<Value>(payload) {
|
||||||
|
Ok(Value::Object(claims_map)) => {
|
||||||
|
claims_map.into_iter().for_each(|(k, v)| {
|
||||||
|
jwt_claims.insert(k, v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(value) => { warning!("Not valid payload map: {}", value); }
|
||||||
|
Err(e) => { warning!("Not valid payload value: {}", e); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
match (payload, claims) {
|
match (payload, claims) {
|
||||||
(Some(_), _) => {}
|
(Some(_), None) => {}
|
||||||
(_, Some(claims)) => {
|
(_, Some(claims)) => {
|
||||||
for claim in claims {
|
for claim in claims {
|
||||||
// TODO support multiple claim types
|
|
||||||
match split_claim(claim) {
|
match split_claim(claim) {
|
||||||
None => { warning!("Claim '{}' do not contains ':'", claim); }
|
None => { warning!("Claim '{}' do not contains ':'", claim); }
|
||||||
Some((k, v)) => { jwt_claims.insert(k, Value::String(v)); }
|
Some((k, v)) => { jwt_claims.insert(k, v); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !jwt_claims.contains_key("sub") {
|
if !jwt_claims.contains_key("sub") {
|
||||||
@@ -123,9 +134,9 @@ fn sign_jwt(slot: &str, pin_opt: &Option<&str>, mut header: Header, payload: &Op
|
|||||||
debugging!("Claims: {:?}", claims);
|
debugging!("Claims: {:?}", claims);
|
||||||
|
|
||||||
let header = opt_result!(header.to_base64(), "Header to base64 failed: {}");
|
let header = opt_result!(header.to_base64(), "Header to base64 failed: {}");
|
||||||
let claims = match payload {
|
let claims = match (payload, claims.is_empty()) {
|
||||||
Some(payload) => Cow::Owned(util::base64_encode_url_safe_no_pad(payload.as_bytes())),
|
(Some(payload), true) => Cow::Owned(util::base64_encode_url_safe_no_pad(payload.as_bytes())),
|
||||||
None => opt_result!(claims.to_base64(), "Claims to base64 failed: {}"),
|
(_, _) => opt_result!(claims.to_base64(), "Claims to base64 failed: {}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tobe_signed = vec![];
|
let mut tobe_signed = vec![];
|
||||||
@@ -148,12 +159,22 @@ fn sign_jwt(slot: &str, pin_opt: &Option<&str>, mut header: Header, payload: &Op
|
|||||||
Ok([&*header, &*claims, &signature].join(SEPARATOR))
|
Ok([&*header, &*claims, &signature].join(SEPARATOR))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_claim(claim: &str) -> Option<(String, String)> {
|
fn split_claim(claim: &str) -> Option<(String, Value)> {
|
||||||
let mut k = String::new();
|
let mut k = String::new();
|
||||||
let mut v = String::new();
|
let mut v = String::new();
|
||||||
|
|
||||||
|
let mut claim_chars = claim.chars().peekable();
|
||||||
|
let ty = if let Some('^') = claim_chars.peek() {
|
||||||
|
let _ = claim_chars.next();
|
||||||
|
match claim_chars.next() {
|
||||||
|
None => return None,
|
||||||
|
Some(t) => Some(t),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let mut is_k = true;
|
let mut is_k = true;
|
||||||
for c in claim.chars() {
|
for c in claim_chars {
|
||||||
if is_k {
|
if is_k {
|
||||||
if c == ':' {
|
if c == ':' {
|
||||||
is_k = false;
|
is_k = false;
|
||||||
@@ -165,5 +186,28 @@ fn split_claim(claim: &str) -> Option<(String, String)> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iff!(is_k, None, Some((k, v)))
|
if is_k {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
match ty {
|
||||||
|
None | Some('s') => Some((k, Value::String(v))),
|
||||||
|
Some('b') => Some((k, Value::Bool(vec!["true", "yes", "1"].contains(&v.as_str())))),
|
||||||
|
Some('i') | Some('n') => {
|
||||||
|
if let Ok(i) = v.parse::<i64>() {
|
||||||
|
return Some((k, Value::Number(Number::from(i))));
|
||||||
|
}
|
||||||
|
if let Ok(f) = v.parse::<f64>() {
|
||||||
|
if let Some(number_f64) = Number::from_f64(f) {
|
||||||
|
return Some((k, Value::Number(number_f64)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
warning!("Bad number: {} in claim: {}", v, claim);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warning!("Unknown type: {} in claim: {}", ty.unwrap(), claim);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user