Skip to content

Commit

Permalink
fix(hc-login): adapt preauth to hc backend changes
Browse files Browse the repository at this point in the history
also include missing requests requirement
  • Loading branch information
meidlinga committed Dec 4, 2023
1 parent 88b47e9 commit 03e1b34
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 22 deletions.
41 changes: 19 additions & 22 deletions hc-login
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# A really nice walk through of how it works is:
# https://auth0.com/docs/get-started/authentication-and-authorization-flow/call-your-api-using-the-authorization-code-flow-with-pkce
import requests
from urllib.parse import urlparse, parse_qs, urlencode
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
from lxml import html
import io
import re
Expand All @@ -13,6 +13,7 @@ import json
from time import time
from base64 import b64decode as base64_decode
from base64 import urlsafe_b64encode as base64url_encode
from bs4 import BeautifulSoup
from Crypto.Random import get_random_bytes
from Crypto.Hash import SHA256
from zipfile import ZipFile
Expand Down Expand Up @@ -124,44 +125,40 @@ while True:
r = session.get(preauth_url, allow_redirects=False)
if r.status_code == 200:
break
if r.status_code == 302 or r.status_code == 301:
if r.status_code > 300 and r.status_code < 400:
preauth_url = r.headers["location"]
# Make relative locations absolute
if not bool(urlparse(preauth_url).netloc):
preauth_url = singlekey_host + preauth_url
continue
print(f"2: {preauth_url=}: failed to fetch {r} {r.text}", file=sys.stderr)
exit(1)

# get the ReturnUrl from the response
query = parse_qs(urlparse(preauth_url).query)
return_url = query["ReturnUrl"][0]
return_url = query["returnUrl"][0]
debug(f"{return_url=}")

headers["RequestVerificationToken"] = r.cookies["X-CSRF-FORM-TOKEN"]
if "X-CSRF-FORM-TOKEN" in r.cookies:
headers["RequestVerificationToken"] = r.cookies["X-CSRF-FORM-TOKEN"]
session.headers.update(headers)

debug("--------")

valid_url = singlekey_host + '/auth/api/v1/authentication/UserExists'
auth_url = singlekey_host + '/auth/api/v1/authentication/login'
soup = BeautifulSoup(r.text, 'html.parser')
requestVerificationToken = soup.find('input', {'name': '__RequestVerificationToken'}).get('value')
r = session.post(preauth_url, data={"UserIdentifierInput.EmailInput.StringValue": email, "__RequestVerificationToken": requestVerificationToken }, allow_redirects=False)

r = session.post(valid_url, json={"username": email})
debug(f"{valid_url=}: {r} {r.text}")
password_url = r.headers['location']
if not bool(urlparse(password_url).netloc):
password_url = singlekey_host + password_url

r = session.get(password_url, allow_redirects=False)
soup = BeautifulSoup(r.text, 'html.parser')
requestVerificationToken = soup.find('input', {'name': '__RequestVerificationToken'}).get('value')

login_fields = {
"username": email,
"password": password,
"keepMeSignedIn": False,
"returnUrl": return_url,
}

r = session.post(auth_url, json=login_fields, allow_redirects=False)

if r.status_code != 200:
debug(f"auth failed: {auth_url=}, {login_fields=} {r} {r.text}")
exit(-1)
r = session.post(password_url, data={"Password": password, "RememberMe": "false", "__RequestVerificationToken": requestVerificationToken }, allow_redirects=False)

debug(f"{auth_url=}, {r} {r.text}")
return_url = json.loads(r.text)["returnUrl"]
if return_url.startswith("/"):
return_url = singlekey_host + return_url

Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
bs4
requests
pycryptodome
websocket-client
sslpsk
Expand Down

0 comments on commit 03e1b34

Please sign in to comment.