1use crate::{Error, STEAM_URL};
2use url::Url;
3
4#[derive(Debug, Clone)]
5pub struct Redirector {
7 url: Url,
8}
9
10impl Redirector {
11 pub fn new<T: AsRef<str>, U: AsRef<str>>(site_url: T, return_url: U) -> Result<Self, Error> {
19 let joined = Url::parse(site_url.as_ref())
20 .map_err(Error::BadUrl)?
21 .join(return_url.as_ref())
22 .map_err(Error::BadUrl)?;
23
24 let openid = SteamAuthRequest::new(site_url.as_ref(), joined.as_str());
25
26 let qs = serde_urlencoded::to_string(&openid).map_err(Error::ParseQueryString)?;
27
28 let mut url = Url::parse(STEAM_URL).map_err(Error::BadUrl)?;
30
31 url.set_query(Some(&qs));
32
33 Ok(Self { url })
34 }
35
36 pub fn create_response(&self) -> Result<http::Response<()>, Error> {
39 http::Response::builder()
40 .status(http::StatusCode::FOUND)
41 .header("Location", self.url.as_str())
42 .body(())
43 .map_err(Error::BuildHttpStruct)
44 }
45
46 pub fn url(&self) -> &Url {
48 &self.url
49 }
50}
51
52#[derive(Serialize)]
53struct SteamAuthRequest<'a> {
54 #[serde(rename = "openid.ns")]
55 ns: &'static str,
56 #[serde(rename = "openid.identity")]
57 identity: &'static str,
58 #[serde(rename = "openid.claimed_id")]
59 claimed_id: &'static str,
60 #[serde(rename = "openid.mode")]
61 mode: &'static str,
62 #[serde(rename = "openid.return_to")]
63 return_to: &'a str,
64 #[serde(rename = "openid.realm")]
65 realm: &'a str,
66}
67
68impl<'a> SteamAuthRequest<'a> {
69 fn new(site_url: &'a str, return_to_joined: &'a str) -> Self {
70 Self {
71 ns: "http://specs.openid.net/auth/2.0",
72 identity: "http://specs.openid.net/auth/2.0/identifier_select",
73 claimed_id: "http://specs.openid.net/auth/2.0/identifier_select",
74 mode: "checkid_setup",
75 realm: site_url,
76 return_to: return_to_joined,
77 }
78 }
79}