Skip to content

Instantly share code, notes, and snippets.

@lukecyca
Created April 21, 2020 07:07
Show Gist options
  • Select an option

  • Save lukecyca/7b5714022cb77a734b532bf11421884d to your computer and use it in GitHub Desktop.

Select an option

Save lukecyca/7b5714022cb77a734b532bf11421884d to your computer and use it in GitHub Desktop.

Revisions

  1. lukecyca created this gist Apr 21, 2020.
    91 changes: 91 additions & 0 deletions chevy.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,91 @@
    import requests
    import urllib
    import re
    import json

    URLSET = {
    'usa': {
    'home': 'https://my.chevrolet.com/home',
    'oc_login': 'https://my.chevrolet.com/oc_login',
    'loginSuccessData': 'https://my.chevrolet.com/api/init/loginSuccessData'
    },
    'canada': {
    'home': 'https://my.gm.ca/gm/en/home',
    'oc_login': 'https://my.gm.ca/gm/en/oc_login',
    'loginSuccessData': 'https://my.gm.ca/gm/en/api/init/loginSuccessData'
    }
    }

    # Choose either 'usa' or 'canada'
    REGION='canada'

    session = requests.Session()

    settings_json_re = re.compile("var SETTINGS = ({.*})")
    id_token_re = re.compile("name='id_token'.*value='(.*)'/>")

    def login(username, password):

    # Initial request - this will redirect to a URL for AAD Authorize Request
    r = session.get(URLSET[REGION]['home'])
    r.raise_for_status()
    initial_url = urllib.parse.urlparse(r.request.url)
    nonce = urllib.parse.parse_qs(initial_url.query).get('nonce')[0]
    print("nonce", nonce)

    m = settings_json_re.search(r.text)
    if not m:
    raise ValueError("SETTINGS not found in response")

    settings_json = json.loads(m[1])
    csrf = settings_json['csrf']
    trans_id = settings_json['transId']

    print(settings_json)
    print("csrf", csrf)
    print("transId", trans_id)

    # Login Request
    r = session.post(
    "https://custlogin.gm.com/gmb2cprod.onmicrosoft.com/B2C_1A_SeamlessMigration_SignUpOrSignIn/SelfAsserted?tx={}&p=B2C_1A_SeamlessMigration_SignUpOrSignIn".format(trans_id),
    {
    "request_type": "RESPONSE",
    "logonIdentifier": username,
    "password": password,
    },
    headers={
    'X-CSRF-TOKEN': csrf,
    }
    )
    r.raise_for_status()

    # Generate Auth Code and ID Token
    r = session.get(
    "https://custlogin.gm.com/gmb2cprod.onmicrosoft.com/B2C_1A_SeamlessMigration_SignUpOrSignIn/api/CombinedSigninAndSignup/confirmed?csrf_token={}&tx={}&p=B2C_1A_SeamlessMigration_SignUpOrSignIn".format(csrf, trans_id)
    )
    r.raise_for_status()
    m = id_token_re.search(r.text)
    if not m:
    raise ValueError("id_token not found in response")

    id_token = m.group(1)
    print("id_token", id_token)

    # Post ID Token
    r = session.post(
    URLSET[REGION]['oc_login'],
    {
    "id_token": id_token
    },
    )
    r.raise_for_status()

    # Get account info
    r = session.get(URLSET[REGION]['loginSuccessData'])
    r.raise_for_status()
    return r.json().get('data')


    account_info = login("[email protected]", "qwertyuiop")
    for vehicle in account_info['vehicleMap'].values():
    print(' '.join([vehicle['year'], vehicle['make'], vehicle['model'], vehicle['vin']]))