Skip to content

Commit

Permalink
Use app API for password authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
Anton Hurlenko committed Oct 20, 2023
1 parent a672390 commit 1555eff
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "orly"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
authors = ["hurlenko"]
description = "Download O'Reilly books as EPUB"
Expand Down
42 changes: 35 additions & 7 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use chrono::{DateTime, Local, NaiveDate};
use futures::stream::{self, StreamExt};

use anyhow::Context;
use log::{error, info, trace};
use log::{debug, error, info, trace};
use reqwest::{
header::{
HeaderMap, HeaderValue, ACCEPT, ACCEPT_ENCODING, COOKIE, UPGRADE_INSECURE_REQUESTS,
Expand All @@ -16,7 +16,10 @@ use reqwest::{

use crate::{
error::{OrlyError, Result},
models::{BillingInfo, Book, Chapter, ChapterMeta, ChaptersResponse, Credentials, TocElement},
models::{
BillingInfo, Book, Chapter, ChapterMeta, ChaptersResponse, Credentials, LoginLookup,
TocElement,
},
};

pub struct Authenticated;
Expand Down Expand Up @@ -71,10 +74,10 @@ impl OreillyClient<Unauthenticated> {

fn default_client() -> ClientBuilder {
let mut headers = HeaderMap::new();
headers.insert(ACCEPT, HeaderValue::from_static("application/json,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"));
headers.insert(ACCEPT, HeaderValue::from_static("*/*"));
headers.insert(ACCEPT_ENCODING, HeaderValue::from_static("gzip, deflate"));
headers.insert(UPGRADE_INSECURE_REQUESTS, HeaderValue::from_static("1"));
headers.insert(USER_AGENT, HeaderValue::from_static("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"));
headers.insert(USER_AGENT, HeaderValue::from_static("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"));
reqwest::Client::builder()
.default_headers(headers)
.cookie_store(true)
Expand Down Expand Up @@ -116,19 +119,44 @@ impl OreillyClient<Unauthenticated> {
email: &str,
password: &str,
) -> Result<OreillyClient<Authenticated>> {
info!("Logging into Safari Books Online...");

let mut map = HashMap::new();
map.insert("email", email);

info!("Checking if password login is possible");
let response = self
.client
.post("https://api.oreilly.com/api/m/v2/auth/lookup/")
.json(&map)
.send()
.await?;

debug!("Email lookup response: {:#?}", response);

let login_lookup = response.json::<LoginLookup>().await?;

if !login_lookup.password_login_allowed {
return Err(crate::error::OrlyError::PasswordLoginUnsupported(
email.to_string(),
));
}

info!("Logging into Safari Books Online...");

map.insert("password", password);

let response = self
.client
.post("https://www.oreilly.com/member/auth/login/")
.post("https://api.oreilly.com/api/v1/auth/login/")
.json(&map)
.basic_auth(
"052079",
Some("00a63c08e9d240b6f4f14b93a135da227e8b9da99103db38c4b4eb4c"),
)
.send()
.await?;

debug!("Auth response: {:#?}", response);

if let Err(err) = response.error_for_status_ref() {
return Err(OrlyError::AuthenticationFailed(format!(
"Login request failed, make sure your email and password are correct: {}",
Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub enum OrlyError {
AuthenticationFailed(String),
#[error("Subscription expired")]
SubscriptionExpired,
#[error("Password login is not supported for account {0}")]
PasswordLoginUnsupported(String),
#[error(transparent)]
Other(#[from] anyhow::Error),
}
Expand Down
5 changes: 5 additions & 0 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ pub(crate) struct Credentials {
pub logged_in: bool,
}

#[derive(Deserialize, Debug)]
pub(crate) struct LoginLookup {
pub password_login_allowed: bool,
}

#[derive(Deserialize, Debug)]
pub struct Author {
pub name: String,
Expand Down

0 comments on commit 1555eff

Please sign in to comment.