Repository: libsql/libsql
File: libsql-server/src/auth/parsers.rs (Rust)

Code before:

    #[test]
    fn parse_http_auth_header_errors_when_auth_header_is_unsupported_scheme() {
        assert_eq!(
            parse_http_auth_header("basic", &HeaderValue::from_str("Bearer abc").ok()).unwrap_err(),
            AuthError::HttpAuthHeaderUnsupportedScheme
        )
    }

    #[test]
    fn parse_http_auth_arg_always() {
        let out = parse_http_basic_auth_arg("always").unwrap();
        assert_eq!(out, Some("always".to_string()));
    }

    const EXAMPLE_JWT_PUBLIC_KEY: &str = include_str!("../../assets/test/auth/example1.pem");
    const EXAMPLE_JWT_PRIVATE_KEY: &str = include_str!("../../assets/test/auth/example1.key");
    const EXAMPLE_JWT: &str = include_str!("../../assets/test/auth/example1.jwt");
    const EXAMPLE3_JWT: &str = include_str!("../../assets/test/auth/example3.jwt");
    const MULTI_JWT_PUBLIC_KEY: &str = include_str!("../../assets/test/auth/combined123.pem");

    #[test]
    fn parse_jwt_key_single_pem() {
        let key = parse_jwt_key(EXAMPLE_JWT_PUBLIC_KEY);
        assert!(matches!(key, Ok(DecodingKeyContainer::Single(_))));
        match key {
            Ok(DecodingKeyContainer::Single(key)) => {
                let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::EdDSA);
                validation.required_spec_claims.remove("exp");
                let decoded = jsonwebtoken::decode::<Token>(&EXAMPLE_JWT, &key, &validation);

                assert!(matches!(
                    decoded,
                    Ok(jsonwebtoken::TokenData {
                        header: _,
                        claims: _
                    })
                ));

                let jsonwebtoken::TokenData { header, claims } = decoded.unwrap();
                assert_eq!(header.alg, jsonwebtoken::Algorithm::EdDSA);

                let claims = format!("{:?}", claims);
                assert_eq!(claims, "Token { id: None, a: None, p: Some(Authorized { read_only: Some(Scopes { namespaces: Some({example1c, example1a, example1b}), tags: None }), read_write: None, read_only_attach: None, read_write_attach: None, ddl_override: None }), exp: Some(+33713-01-29T21:47:33Z) }");
            }
            _ => {}
        }
    }

    #[test]
    fn parse_jwt_key_multiple_pems() {

Review comment (suggestion):
at this point we know the type, so we can avoid a few levels of nesting by doing
`let DecodingKeyContainer::Single(key) = key.unwrap() else {};`

Code after:
        )
    }

    #[test]
    fn parse_http_auth_arg_always() {
        let out = parse_http_basic_auth_arg("always").unwrap();
        assert_eq!(out, Some("always".to_string()));
    }

    // Examples created via libsql-server/scripts/gen_jwt_test_assets.py
    const EXAMPLE_JWT_PUBLIC_KEY: &str = include_str!("../../assets/test/auth/example1.pem");
    const EXAMPLE_JWT_PRIVATE_KEY: &str = include_str!("../../assets/test/auth/example1.key");
    const EXAMPLE_JWT: &str = include_str!("../../assets/test/auth/example1.jwt");
    const EXAMPLE3_JWT: &str = include_str!("../../assets/test/auth/example3.jwt");
    const MULTI_JWT_PUBLIC_KEY: &str = include_str!("../../assets/test/auth/combined123.pem");

    #[test]
    fn parse_jwt_keys_single_pem() {
        let keys = parse_jwt_keys(EXAMPLE_JWT_PUBLIC_KEY);
        assert_eq!(keys.as_ref().map_or(0, |v| v.len()), 1);
        let key = keys.unwrap().into_iter().next().unwrap();

        let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::EdDSA);
        validation.required_spec_claims.remove("exp");
        let decoded = jsonwebtoken::decode::<Token>(&EXAMPLE_JWT, &key, &validation);

        assert!(matches!(
            decoded,
            Ok(jsonwebtoken::TokenData {
                header: _,
                claims: _
            })
        ));

        let jsonwebtoken::TokenData { header, claims } = decoded.unwrap();
        assert_eq!(header.alg, jsonwebtoken::Algorithm::EdDSA);

        assert!(claims.p.is_some());
        let Some(authorized) = claims.p else {
            panic!("Assertion should have already failed");
        };

        let scopes: Scopes =
            serde_json::from_str(r##"{"ns":["example1a","example1b","example1c"]}"##)
                .expect("JSON failed to parse");
        assert_eq!(authorized.read_only, Some(scopes));
    }

    #[test]
    fn parse_jwt_keys_multiple_pems() {
        let keys = parse_jwt_keys(MULTI_JWT_PUBLIC_KEY);