Fix #210
Update HTTP Headers Add check for subscription expiration Add a script to register to ORLY
This commit is contained in:
parent
47ecfb3dc4
commit
d8a22bbb31
2 changed files with 163 additions and 8 deletions
153
register_user.py
Normal file
153
register_user.py
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
import re
|
||||
import requests
|
||||
import safaribooks
|
||||
|
||||
REGISTER_URL = safaribooks.SAFARI_BASE_URL + "/register/"
|
||||
CHECK_EMAIL = safaribooks.SAFARI_BASE_URL + "/check-email-availability/"
|
||||
CHECK_PWD = safaribooks.SAFARI_BASE_URL + "/check-password/"
|
||||
|
||||
# DEBUG
|
||||
USE_PROXY = False
|
||||
PROXIES = {"https": "https://127.0.0.1:8080"}
|
||||
|
||||
CSRF_TOKEN_RE = re.compile(r"(?<=name='csrfmiddlewaretoken' value=')([^']+)")
|
||||
|
||||
|
||||
class Register:
|
||||
def __init__(self, email, password, first_name, second_name, country="US", referrer="podcast"):
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.first_name = first_name
|
||||
self.second_name = second_name
|
||||
self.country = country
|
||||
self.referrer = referrer
|
||||
|
||||
self.csrf = None
|
||||
|
||||
self.session = requests.Session()
|
||||
if USE_PROXY: # DEBUG
|
||||
self.session.proxies = PROXIES
|
||||
self.session.verify = False
|
||||
|
||||
self.session.headers.update(safaribooks.SafariBooks.HEADERS)
|
||||
self.session.headers.update({
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"Referer": REGISTER_URL
|
||||
})
|
||||
|
||||
self.register()
|
||||
|
||||
def handle_cookie_update(self, set_cookie_headers):
|
||||
for morsel in set_cookie_headers:
|
||||
# Handle Float 'max-age' Cookie
|
||||
if safaribooks.SafariBooks.COOKIE_FLOAT_MAX_AGE_PATTERN.search(morsel):
|
||||
cookie_key, cookie_value = morsel.split(";")[0].split("=")
|
||||
self.session.cookies.set(cookie_key, cookie_value)
|
||||
|
||||
def requests_provider(self, url, is_post=False, data=None, perform_redirect=True, check_200=True, **kwargs):
|
||||
try:
|
||||
response = getattr(self.session, "post" if is_post else "get")(
|
||||
url,
|
||||
data=data,
|
||||
allow_redirects=False,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
self.handle_cookie_update(response.raw.headers.getlist("Set-Cookie"))
|
||||
|
||||
except (requests.ConnectionError, requests.ConnectTimeout, requests.RequestException) as request_exception:
|
||||
print("Error: ", str(request_exception))
|
||||
return 0
|
||||
|
||||
if response.is_redirect and perform_redirect:
|
||||
return self.requests_provider(response.next.url, is_post, None, perform_redirect, check_200, **kwargs)
|
||||
|
||||
if check_200 and response.status_code != 200:
|
||||
print("Invalid response code:\n", response.text)
|
||||
return 0
|
||||
|
||||
return response
|
||||
|
||||
def register(self):
|
||||
# Take first cookie + csrf
|
||||
response = self.requests_provider(REGISTER_URL)
|
||||
if response == 0:
|
||||
print("Error 0x1: unable to reach registration page!")
|
||||
exit(1)
|
||||
|
||||
if "csrfmiddlewaretoken' value='" not in response.text:
|
||||
print("Error 0x2: CSRF token not present")
|
||||
exit(1)
|
||||
|
||||
csrf_search = CSRF_TOKEN_RE.findall(response.text)
|
||||
if not len(csrf_search):
|
||||
print("Error 0x3: CSRF token RE error")
|
||||
exit(1)
|
||||
|
||||
self.csrf = csrf_search[0]
|
||||
|
||||
# Check user validity
|
||||
response = self.requests_provider(CHECK_EMAIL, params={"email": self.email})
|
||||
if response == 0:
|
||||
print("Error 0x4: unable to check email!")
|
||||
exit(1)
|
||||
|
||||
response_dict = response.json()
|
||||
if not response_dict["success"]:
|
||||
print("Error 0x5:", response_dict["message"])
|
||||
exit(1)
|
||||
|
||||
# Check password validity
|
||||
response = self.requests_provider(CHECK_PWD, is_post=True, data={
|
||||
"csrfmiddlewaretoken": self.csrf,
|
||||
"password1": self.password,
|
||||
"field_name": "password1"
|
||||
})
|
||||
if response == 0:
|
||||
print("Error 0x6: unable to check password!")
|
||||
exit(1)
|
||||
|
||||
response_dict = response.json()
|
||||
if not response_dict["valid"]:
|
||||
print("Error 0x7:", response_dict["msg"])
|
||||
exit(1)
|
||||
|
||||
# Register
|
||||
response = self.requests_provider(REGISTER_URL, is_post=True, data={
|
||||
"next": "",
|
||||
"trial_length": 10,
|
||||
"csrfmiddlewaretoken": self.csrf,
|
||||
"first_name": self.first_name,
|
||||
"last_name": self.second_name,
|
||||
"email": self.email,
|
||||
"password1": self.password,
|
||||
"country": self.country,
|
||||
"referrer": "podcast",
|
||||
"recently_viewed_bits": "[]"
|
||||
}, check_200=False)
|
||||
if response == 0:
|
||||
print("Error 0x8: unable to register!")
|
||||
exit(1)
|
||||
|
||||
elif response.status_code != 201:
|
||||
print("Error: 0x9: invalid status code while registering!")
|
||||
exit(1)
|
||||
|
||||
print("[*] Account registered: \nEMAIL: %s\nPASSWORD: %s" % (self.email, self.password))
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if len(sys.argv) < 3:
|
||||
print("[!] Error: too few arguments.\nRun `register_user.py EMAIL PASSWORD`.")
|
||||
exit(1)
|
||||
|
||||
elif len(sys.argv) > 3:
|
||||
print("[!] Error: too much arguments, try to enclose the string with quote '\"'.")
|
||||
exit(1)
|
||||
|
||||
FIRST_NAME = "Safari"
|
||||
SECOND_NAME = "Download"
|
||||
|
||||
Register(sys.argv[1], sys.argv[2], FIRST_NAME, SECOND_NAME)
|
||||
|
|
@ -299,13 +299,12 @@ class SafariBooks:
|
|||
"</ncx>"
|
||||
|
||||
HEADERS = {
|
||||
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"origin": SAFARI_BASE_URL,
|
||||
"referer": LOGIN_ENTRY_URL,
|
||||
"upgrade-insecure-requests": "1",
|
||||
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/60.0.3112.113 Safari/537.36"
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Referer": LOGIN_ENTRY_URL,
|
||||
"Upgrade-Insecure-Requests": "1",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.163 Safari/537.36"
|
||||
}
|
||||
|
||||
COOKIE_FLOAT_MAX_AGE_PATTERN = re.compile(r'(max-age=\d*\.\d*)', re.IGNORECASE)
|
||||
|
|
@ -522,9 +521,12 @@ class SafariBooks:
|
|||
if response == 0:
|
||||
self.display.exit("Login: unable to reach Safari Books Online. Try again...")
|
||||
|
||||
if response.status_code != 200:
|
||||
elif response.status_code != 200:
|
||||
self.display.exit("Authentication issue: unable to access profile page.")
|
||||
|
||||
elif "user_type\":\"Expired" in response.text:
|
||||
self.display.exit("Authentication issue: account subscription expired.")
|
||||
|
||||
self.display.info("Successfully authenticated.", state=True)
|
||||
|
||||
def get_book_info(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue