1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use crate::{
    base_headers, get_http_client,
    my_plex::{MyPlexAccount, MyPlexApiErrorResponse},
};

const MYPLEX_LOGIN_URL: &str = "https://plex.tv/api/v2/users/signin";
const MYPLEX_ACCOUNT_INFO_URL: &str = "https://plex.tv/api/v2/user?includeSubscriptions=1";

impl MyPlexAccount {
    /// Log in to [MyPlex](http://app.plex.tv) using username and password.
    pub fn login(username: &str, password: &str) -> crate::Result<Self> {
        let params = [
            ("login", username),
            ("password", password),
            ("mememberMe", "true"),
        ];

        let mut response = get_http_client()?
            .post(MYPLEX_LOGIN_URL)
            .form(&params)
            .headers(base_headers())
            .header(reqwest::header::ACCEPT, "application/json")
            .send()?;
        MyPlexAccount::handle_login(&mut response)
    }

    /// Log in to [MyPlex](http://app.plex.tv) using existing authentication token.
    pub fn by_token(auth_token: &str) -> crate::Result<Self> {
        let mut response = get_http_client()?
            .get(MYPLEX_ACCOUNT_INFO_URL)
            .headers(base_headers())
            .header(reqwest::header::ACCEPT, "application/json")
            .header("X-Plex-Token", auth_token)
            .send()?;

        MyPlexAccount::handle_login(&mut response)
    }

    fn handle_login(r: &mut reqwest::Response) -> crate::Result<Self> {
        match r.status() {
            reqwest::StatusCode::OK | reqwest::StatusCode::CREATED => {
                Ok(r.json::<MyPlexAccount>()?)
            }
            _ => Err(crate::error::PlexApiError::from(
                r.json::<MyPlexApiErrorResponse>()?,
            )),
        }
    }
}