oauth1_twitter/endpoints/
authenticate.rs

1//! https://developer.twitter.com/en/docs/authentication/api-reference/authenticate
2
3use http_api_client_endpoint::{http::Method, Body, Endpoint, Request, Response};
4use url::Url;
5
6pub const URL: &str = "https://api.twitter.com/oauth/authenticate";
7
8//
9#[derive(Debug, Clone)]
10pub struct AuthenticateEndpoint {
11    pub oauth_token: String,
12    pub force_login: Option<bool>,
13    pub screen_name: Option<String>,
14}
15impl AuthenticateEndpoint {
16    pub fn new(oauth_token: impl AsRef<str>) -> Self {
17        Self {
18            oauth_token: oauth_token.as_ref().into(),
19            force_login: None,
20            screen_name: None,
21        }
22    }
23
24    pub fn with_force_login(mut self, force_login: bool) -> Self {
25        self.force_login = Some(force_login);
26        self
27    }
28
29    pub fn with_screen_name(mut self, screen_name: impl AsRef<str>) -> Self {
30        self.screen_name = Some(screen_name.as_ref().into());
31        self
32    }
33
34    pub fn authorization_url(&self) -> Result<String, AuthenticateEndpointError> {
35        let request = self.render_request()?;
36        Ok(request.uri().to_string())
37    }
38}
39
40impl Endpoint for AuthenticateEndpoint {
41    type RenderRequestError = AuthenticateEndpointError;
42
43    type ParseResponseOutput = ();
44    type ParseResponseError = AuthenticateEndpointError;
45
46    fn render_request(&self) -> Result<Request<Body>, Self::RenderRequestError> {
47        let mut url = Url::parse(URL).map_err(AuthenticateEndpointError::MakeRequestUrlFailed)?;
48
49        let query = AuthenticateRequestQuery {
50            oauth_token: self.oauth_token.to_owned(),
51            force_login: self.force_login,
52            screen_name: self.screen_name.to_owned(),
53        };
54
55        let query = serde_qs::to_string(&query)
56            .map_err(AuthenticateEndpointError::SerRequestUrlQueryFailed)?;
57
58        url.set_query(Some(query.as_str()));
59
60        let request = Request::builder()
61            .method(Method::GET)
62            .uri(url.as_str())
63            .body(vec![])
64            .map_err(AuthenticateEndpointError::MakeRequestFailed)?;
65
66        Ok(request)
67    }
68
69    fn parse_response(
70        &self,
71        _response: Response<Body>,
72    ) -> Result<Self::ParseResponseOutput, Self::ParseResponseError> {
73        unreachable!()
74    }
75}
76
77//
78pub type AuthenticateRequestQuery = crate::endpoints::authorize::AuthorizeRequestQuery;
79
80//
81//
82//
83pub type AuthenticateEndpointError = crate::endpoints::authorize::AuthorizeEndpointError;
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_render_request() {
91        //
92        let req = AuthenticateEndpoint::new("Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hxxxxxx")
93            .render_request()
94            .unwrap();
95        assert_eq!(req.method(), Method::GET);
96        assert_eq!(req.uri(), "https://api.twitter.com/oauth/authenticate?oauth_token=Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hxxxxxx");
97
98        //
99        let req = AuthenticateEndpoint::new("Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hxxxxxx")
100            .with_force_login(true)
101            .with_screen_name("xxx")
102            .render_request()
103            .unwrap();
104        assert_eq!(req.method(), Method::GET);
105        assert_eq!(req.uri(), "https://api.twitter.com/oauth/authenticate?oauth_token=Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hxxxxxx&force_login=true&screen_name=xxx");
106    }
107}