use aep_core::*;
fn accepted(json: &str) -> bool {
parse_inspect_document(json.as_bytes())
.is_ok_and(|document| validate_inspect_document(&document).is_ok())
}
fn document(body: &str) -> String {
format!(
r#"{{"aep_version":"1.0","bindings":{{"supported":["http"]}},
"core":{{"signing_algorithms":["EdDSA","ES256"]}},"http":{{}},
"identity":{{"methods":[]}},"service":{{"did":"did:web:api.example.com"}},{body}}}"#
)
}
#[test]
fn accepts_the_published_minimal_document() {
assert!(accepted(&document(
r#""commands":{"supported":["inspect"]}"#
)));
}
#[test]
fn command_advertisements() {
assert!(!accepted(&document(
r#""commands":{"supported":["enroll"]}"#
)));
assert!(!accepted(&document(
r#""commands":{"supported":["inspect","authenticate"]}"#
)));
}
#[test]
fn grant_type_advertisements() {
assert!(!accepted(&document(
r#""commands":{"supported":["grant","inspect"]}"#
)));
assert!(!accepted(&document(
r#""commands":{"supported":["revoke","inspect"]}"#
)));
let enrolled = |body: &str| {
document(body).replace(
r#""identity":{"methods":[]}"#,
r#""identity":{"methods":["did:web"]}"#,
)
};
assert!(accepted(&enrolled(
r#""commands":{"supported":["grant","inspect"],"grant_types":["oauth-bearer"]}"#
)));
assert!(!accepted(&enrolled(
r#""commands":{"supported":["grant","inspect"],"grant_types":["oauth_bearer"]}"#
)));
assert!(!accepted(&enrolled(
r#""commands":{"supported":["grant","inspect"],"grant_types":["oauth-bearer"],
"grant_types_config":{"api-key":{}}}"#
)));
assert!(!accepted(&enrolled(
r#""commands":{"supported":["grant","inspect"],"grant_types":["oauth-bearer"],
"grant_types_config":{"Oauth-Bearer":{}}}"#
)));
assert!(accepted(&enrolled(
r#""commands":{"supported":["grant","inspect"],"grant_types":["oauth-bearer"],
"grant_types_config":{"oauth-bearer":{"supports_per_credential_revoke":"true"}}}"#
)));
}
#[test]
fn authenticated_commands_require_an_identity_method() {
for command in ["enroll", "grant", "revoke", "status"] {
let body = format!(r#""commands":{{"supported":["inspect","{command}"]}}"#);
assert!(!accepted(&document(&body)), "{command}");
}
assert!(accepted(
&document(r#""commands":{"supported":["inspect","status"]}"#).replace(
r#""identity":{"methods":[]}"#,
r#""identity":{"methods":["did:web"]}"#
)
));
}
#[test]
fn signing_algorithm_advertisements() {
let with = |algorithms: &str| {
document(r#""commands":{"supported":["inspect"]}"#).replace(
r#""signing_algorithms":["EdDSA","ES256"]"#,
&format!(r#""signing_algorithms":{algorithms}"#),
)
};
assert!(!accepted(&with(r#"["ES256"]"#)));
assert!(!accepted(&with(r#"["EdDSA"]"#)));
assert!(!accepted(&with("[]")));
assert!(accepted(&with(r#"["EdDSA","ES256"]"#)));
}
#[test]
fn authentication_method_advertisements() {
let methods: Vec<String> = (1..=17)
.map(|index| format!("\"method-{index:02}\""))
.collect();
let body = format!(
r#""commands":{{"supported":["inspect"]}},"authentication":{{"methods":[{}]}}"#,
methods.join(",")
);
assert!(!accepted(&document(&body)));
assert!(accepted(&document(
r#""commands":{"supported":["inspect"]},"authentication":{"methods":["aep-jwt"]}"#
)));
assert!(!accepted(&document(
r#""commands":{"supported":["inspect"]},"authentication":{"methods":["AEP-JWT"]}"#
)));
assert!(!accepted(&document(
r#""commands":{"supported":["inspect"]},"authentication":{"methods":["aep-jwt","aep-jwt"]}"#
)));
}
#[test]
fn claim_advertisements() {
assert!(!accepted(&document(
r#""commands":{"supported":["inspect"]},"claims":{"required":["Contact.Email"]}"#
)));
assert!(accepted(&document(
r#""commands":{"supported":["inspect"]},"claims":{"required":["example.future.claim"]}"#
)));
}
#[test]
fn openapi_advertisements() {
let with = |http: &str| {
document(r#""commands":{"supported":["inspect"]}"#)
.replace(r#""http":{}"#, &format!(r#""http":{http}"#))
};
assert!(accepted(&with(
r#"{"openapi":{"path_matching":{"trailing_slash":"strict"},"url":"/openapi.json"}}"#
)));
assert!(!accepted(&with(
r#"{"openapi":{"path_matching":{"trailing_slash":"strict"},"url":"not a URI"}}"#
)));
assert!(!accepted(&with(
r#"{"openapi":{"path_matching":{"trailing_slash":"strict"},"url":""}}"#
)));
}
#[test]
fn endpoint_base_advertisements() {
let with = |base: &str| {
document(r#""commands":{"supported":["inspect"]}"#).replace(
r#""http":{}"#,
&format!(r#""http":{{"endpoint_base":"{base}"}}"#),
)
};
assert!(accepted(&with("/aep/")));
assert!(accepted(&with("/aep")));
for base in ["aep/", "//evil.example/", "/aep/?next=", "/aep/#fragment"] {
assert!(!accepted(&with(base)), "{base}");
}
}
#[test]
fn service_and_extension_advertisements() {
let base = document(r#""commands":{"supported":["inspect"]}"#);
assert!(!accepted(&base.replace(
r#""did":"did:web:api.example.com""#,
r#""did":"https://api.example.com""#
)));
assert!(accepted(&document(
r#""commands":{"supported":["inspect"]},"extensions":{"supported":[]}"#
)));
assert!(!accepted(&document(
r#""commands":{"supported":["inspect"]},"extensions":{"supported":["openapi-authentication"]}"#
)));
}
#[test]
fn forward_compatible_advertisements() {
assert!(accepted(&document(
r#""commands":{"supported":["inspect","future-command"]},"future_section":{"enabled":true}"#
)
.replace(r#""supported":["http"]"#, r#""supported":["http","future-binding"]"#)
.replace(r#""aep_version":"1.0""#, r#""aep_version":"1.7""#)));
}
#[test]
fn binding_advertisements() {
let base = document(r#""commands":{"supported":["inspect"]}"#);
assert!(!accepted(
&base.replace(r#""supported":["http"]"#, r#""supported":[]"#)
));
assert!(!accepted(&base.replace(
r#""supported":["http"]"#,
r#""supported":["future"]"#
)));
}
#[test]
fn version_compatibility() {
assert!(is_version_compatible("1.0", "1.0"));
assert!(is_version_compatible("1.7", "1.0"));
assert!(!is_version_compatible("2.0", "1.0"));
assert!(!is_version_compatible("1", "1.0"));
assert!(!is_version_compatible("1.0", "bad"));
assert!(!is_version_compatible("01.0", "1.0"));
}
#[test]
fn rejects_documents_that_are_not_objects() {
assert!(parse_inspect_document(b"[]").is_err());
assert!(parse_inspect_document(b"not json").is_err());
assert!(parse_inspect_document(b"{}").is_err());
}