use super::funejson::Value; use super::auth_access_token_read_access_token::{access_check_to_value, access_denied}; /// The last word on a token read_access_token accepted, once the caller has /// looked up the user and the revoked list: a logged-out token, or one /// issued before the user's token version was bumped (a password change), /// no longer stands. pub fn confirm_access_token(check: &AccessCheck, current_token_version: Option, revoked: bool) -> AccessCheck { if !check.ok { return check.clone(); } let current = match current_token_version { Some(v) => v, None => return access_denied("user_not_found", "the token's user no longer exists"), }; if revoked { return access_denied("token_revoked", "the token has been revoked by logging out"); } if check.token_version != Some(current) { return access_denied( "token_revoked", "the token was issued before the user's tokens were revoked (password changed)", ); } check.clone() } fn access_check_from_value(value: &Value) -> AccessCheck { let text = |key: &str| match value.get(key) { Value::Str(s) => Some(s.clone()), _ => None, }; AccessCheck { ok: value.get("ok").as_bool(), subject: text("subject"), token_version: match value.get("tokenVersion") { Value::Int(i) => Some(*i), _ => None, }, jti: text("jti"), expires_at: text("expiresAt"), claims: match value.get("claims") { Value::Null => None, other => Some(other.clone()), }, error: text("error"), message: text("message"), } } pub fn fune_vector(args: &[Value]) -> Value { let current = match &args[1] { Value::Int(i) => Some(*i), Value::Null => None, _ => panic!("currentTokenVersion must be a whole number or null"), }; let revoked = match &args[2] { Value::Bool(b) => *b, _ => panic!("revoked must be true or false"), }; access_check_to_value(&confirm_access_token(&access_check_from_value(&args[0]), current, revoked)) }