Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions src/sessionrequest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ pub struct BaseRequest {
deserialize_with = "crate::util::de_int_key"
)]
pub labels: HashMap<usize, TranslatedString>,
/// Host to use in the session QR (`Qr.u`), overriding the IRMA server's default.
/// The server validates this against the requestor's configured `host_perms` allowlist.
/// Requires irmago v0.14.0 or newer on the server side.
#[serde(skip_serializing_if = "Option::is_none", default)]
pub host: Option<String>,
}

/// IRMA session requests
Expand Down Expand Up @@ -179,6 +184,7 @@ impl BaseRequestBuilder {
return_url: None,
augment_return: false,
labels: HashMap::new(),
host: None,
},
}
}
Expand Down Expand Up @@ -215,6 +221,11 @@ impl BaseRequestBuilder {
self.base.return_url = Some(return_url);
self.base.augment_return = true;
}

fn host(&mut self, host: String) {
debug_assert!(self.base.host.is_none());
self.base.host = Some(host);
}
}

impl Default for BaseRequestBuilder {
Expand Down Expand Up @@ -276,6 +287,14 @@ impl DisclosureRequestBuilder {
self.base.augmented_return_url(return_url);
self
}

/// Set the host to use in the session QR, overriding the IRMA server's default.
/// The server validates this against the requestor's configured `host_perms` allowlist
/// (requires irmago v0.14.0 or newer).
pub fn host(mut self, host: String) -> DisclosureRequestBuilder {
self.base.host(host);
self
}
}

/// Build a signature request
Expand Down Expand Up @@ -335,6 +354,14 @@ impl SignatureRequestBuilder {
self.base.augmented_return_url(return_url);
self
}

/// Set the host to use in the session QR, overriding the IRMA server's default.
/// The server validates this against the requestor's configured `host_perms` allowlist
/// (requires irmago v0.14.0 or newer).
pub fn host(mut self, host: String) -> SignatureRequestBuilder {
self.base.host(host);
self
}
}

/// Build a request to issue one or more credentials
Expand Down Expand Up @@ -401,6 +428,14 @@ impl IssuanceRequestBuilder {
self.base.augmented_return_url(return_url);
self
}

/// Set the host to use in the session QR, overriding the IRMA server's default.
/// The server validates this against the requestor's configured `host_perms` allowlist
/// (requires irmago v0.14.0 or newer).
pub fn host(mut self, host: String) -> IssuanceRequestBuilder {
self.base.host(host);
self
}
}

/// An IRMA request extended with extra information for the server on how to execute it.
Expand Down Expand Up @@ -543,6 +578,53 @@ mod tests {
);
}

#[test]
fn test_host_request() {
// host is omitted from the serialized request when not set
let req1 = DisclosureRequestBuilder::new()
.add_discon(vec![vec![AttributeRequest::Simple("a.b.c.d".into())]])
.build();
assert!(!serde_json::to_string(&req1).unwrap().contains("host"));

// host is serialized as "host" when set, and survives a round-trip
let req2 = DisclosureRequestBuilder::new()
.add_discon(vec![vec![AttributeRequest::Simple("a.b.c.d".into())]])
.host("https://example.com".into())
.build();
assert_eq!("{\"@context\":\"https://irma.app/ld/request/disclosure/v2\",\"disclose\":[[[\"a.b.c.d\"]]],\"host\":\"https://example.com\"}", serde_json::to_string(&req2).unwrap());
assert_eq!(
req2,
serde_json::from_str(&serde_json::to_string(&req2).unwrap()).unwrap()
);

// the host setter is available on every public builder
let req3 = SignatureRequestBuilder::new("testmessage".into())
.add_discon(vec![vec![AttributeRequest::Simple("a.b.c.d".into())]])
.host("https://signature.example.com".into())
.build();
assert_eq!("{\"@context\":\"https://irma.app/ld/request/signature/v2\",\"message\":\"testmessage\",\"disclose\":[[[\"a.b.c.d\"]]],\"host\":\"https://signature.example.com\"}", serde_json::to_string(&req3).unwrap());
assert_eq!(
req3,
serde_json::from_str(&serde_json::to_string(&req3).unwrap()).unwrap()
);

let req4 = IssuanceRequestBuilder::new()
.add_credential(Credential {
credential: "a.b.c".into(),
validity: Some(123456789),
attributes: hashmap![
"d".into() => "e".into(),
],
})
.host("https://issuance.example.com".into())
.build();
assert_eq!("{\"@context\":\"https://irma.app/ld/request/issuance/v2\",\"credentials\":[{\"credential\":\"a.b.c\",\"validity\":123456789,\"attributes\":{\"d\":\"e\"}}],\"host\":\"https://issuance.example.com\"}", serde_json::to_string(&req4).unwrap());
assert_eq!(
req4,
serde_json::from_str(&serde_json::to_string(&req4).unwrap()).unwrap()
);
}

#[test]
fn test_signature_request() {
let req1 = SignatureRequestBuilder::new("testmessage".into())
Expand Down
Loading