feat: claim types
This commit is contained in:
@@ -53,14 +53,25 @@ impl Command for CommandImpl {
|
||||
..Default::default()
|
||||
};
|
||||
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) {
|
||||
(Some(_), _) => {}
|
||||
(Some(_), None) => {}
|
||||
(_, Some(claims)) => {
|
||||
for claim in claims {
|
||||
// TODO support multiple claim types
|
||||
match split_claim(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") {
|
||||
@@ -123,9 +134,9 @@ fn sign_jwt(slot: &str, pin_opt: &Option<&str>, mut header: Header, payload: &Op
|
||||
debugging!("Claims: {:?}", claims);
|
||||
|
||||
let header = opt_result!(header.to_base64(), "Header to base64 failed: {}");
|
||||
let claims = match payload {
|
||||
Some(payload) => Cow::Owned(util::base64_encode_url_safe_no_pad(payload.as_bytes())),
|
||||
None => opt_result!(claims.to_base64(), "Claims to base64 failed: {}"),
|
||||
let claims = match (payload, claims.is_empty()) {
|
||||
(Some(payload), true) => Cow::Owned(util::base64_encode_url_safe_no_pad(payload.as_bytes())),
|
||||
(_, _) => opt_result!(claims.to_base64(), "Claims to base64 failed: {}"),
|
||||
};
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
fn split_claim(claim: &str) -> Option<(String, String)> {
|
||||
fn split_claim(claim: &str) -> Option<(String, Value)> {
|
||||
let mut k = 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;
|
||||
for c in claim.chars() {
|
||||
for c in claim_chars {
|
||||
if is_k {
|
||||
if c == ':' {
|
||||
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