Functional Weave
Code in Rust

auth.access-token@1.0.0

impl/rust/confirm_access_token.rs

2,180 bytes · the Rust implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

use super::funejson::Value;  ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::auth_access_token_read_access_token::{access_check_to_value, access_denied};  ← readAccessToken, another function of this group · built into the same file, even by a slim install

/// 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<i64>, 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))
}