oauth2_types/
webfinger.rs1use serde::{Deserialize, Serialize};
12use url::Url;
13
14#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
16pub struct WebFingerResponse {
17    subject: String,
19
20    links: Vec<WebFingerLink>,
22}
23
24impl WebFingerResponse {
25    #[must_use]
27    pub const fn new(subject: String) -> Self {
28        Self {
29            subject,
30            links: Vec::new(),
31        }
32    }
33
34    #[must_use]
36    pub fn with_link(mut self, link: WebFingerLink) -> Self {
37        self.links.push(link);
38        self
39    }
40
41    #[must_use]
43    pub fn with_issuer(self, issuer: Url) -> Self {
44        self.with_link(WebFingerLink::issuer(issuer))
45    }
46}
47
48#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
50#[serde(tag = "rel")]
51pub enum WebFingerLink {
52    #[serde(rename = "http://openid.net/specs/connect/1.0/issuer")]
54    OidcIssuer {
55        href: Url,
57    },
58}
59
60impl WebFingerLink {
61    #[must_use]
63    pub const fn issuer(href: Url) -> Self {
64        Self::OidcIssuer { href }
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use serde_json::json;
71
72    use super::*;
73
74    #[test]
75    fn serialize_webfinger_response_test() {
76        let res = WebFingerResponse::new("acct:john@example.com".to_owned())
77            .with_issuer(Url::parse("https://account.example.com/").unwrap());
78
79        let res = serde_json::to_value(res).unwrap();
80
81        assert_eq!(
82            res,
83            json!({
84                "subject": "acct:john@example.com",
85                "links": [{
86                    "rel": "http://openid.net/specs/connect/1.0/issuer",
87                    "href": "https://account.example.com/",
88                }]
89            })
90        );
91    }
92}