Skip to content

Commit

Permalink
Merge pull request #189 from itchannel/1.34
Browse files Browse the repository at this point in the history
1.34
  • Loading branch information
itchannel authored Jun 30, 2022
2 parents 98509f6 + a875b07 commit 681b085
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 28 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- https://github.com/degrashopper - Fixing 401 error for certain installs
- https://github.com/tonesto7 - Extra window statuses and sensors
- https://github.com/JacobWasFramed - Updated unit conversions
- https://github.com/heehoo59 - French Translation

## 1.23 Breaking Change
The way the units work has been changed so if updating please go to "Integrations" and click options on fordpass and choose your preferred units (miles/km etc) and restart HA. Not doing this will result in an error!!
Expand Down
3 changes: 2 additions & 1 deletion custom_components/fordpass/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ async def validate_input(hass: core.HomeAssistant, data):
Data has the keys from DATA_SCHEMA with values provided by the user.
"""
_LOGGER.debug(data[REGION])
vehicle = Vehicle(data[CONF_USERNAME], data[CONF_PASSWORD], data[VIN], data[REGION])
configPath = hass.config.path("custom_components/fordpass/" + data[CONF_USERNAME] + "_fordpass_token.txt")
vehicle = Vehicle(data[CONF_USERNAME], data[CONF_PASSWORD], data[VIN], data[REGION], 1, configPath)

try:
result = await hass.async_add_executor_job(vehicle.auth)
Expand Down
145 changes: 119 additions & 26 deletions custom_components/fordpass/fordpass_new.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import hashlib
import json
import logging
import os
import random
import re
import requests
import string
import time

import requests
from base64 import urlsafe_b64encode, urlsafe_b64decode
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

Expand Down Expand Up @@ -58,47 +63,135 @@ def __init__(
_LOGGER.debug(configLocation)
self.token_location = configLocation

def base64UrlEncode(self,data):
return urlsafe_b64encode(data).rstrip(b'=')

def generate_hash(self, code):
m = hashlib.sha256()
m.update(code.encode('utf-8'))
return self.base64UrlEncode(m.digest()).decode('utf-8')


def auth(self):
"""Authenticate and store the token"""
_LOGGER.debug("New System")
"""New Authentication System """
# Auth Step1
headers = {
**defaultHeaders,
'Content-Type': 'application/json',
}
code1 = ''.join(random.choice(string.ascii_lowercase) for i in range(43))
code_verifier = self.generate_hash(code1)
url1 = "https://sso.ci.ford.com/v1.0/endpoint/default/authorize?redirect_uri=fordapp://userauthorized&response_type=code&scope=openid&max_age=3600&client_id=9fb503e0-715b-47e8-adfd-ad4b7770f73b&code_challenge=" + code_verifier + "&code_challenge_method=S256"
r = session.get(
url1,
headers=headers,
)

test = re.findall('data-ibm-login-url="(.*)"\s', r.text)[0]
nextUrl = "https://sso.ci.ford.com" + test


# Auth Step2
headers = {
**defaultHeaders,
"Content-Type": "application/x-www-form-urlencoded",
}
data = {
"client_id": "9fb503e0-715b-47e8-adfd-ad4b7770f73b",
"grant_type": "password",
"username": self.username,
"password": self.password,
"operation": "verify",
"login-form-type": "password",
"username" : self.username,
"password" : self.password

}
r = session.post(
nextUrl,
headers=headers,
data = data,
allow_redirects=False

)

if r.status_code == 302:
nextUrl = r.headers["Location"]
else:
r.raise_for_status()

# Auth Step3
headers = {
**defaultHeaders,
'Content-Type': 'application/json',
}

r = session.get(
nextUrl,
headers = headers,
allow_redirects=False
)




if r.status_code == 302:
nextUrl = r.headers["Location"]
query = requests.utils.urlparse(nextUrl).query
params = dict(x.split('=') for x in query.split('&'))
code = params["code"]
grant_id = params["grant_id"]
else:
r.raise_for_status()

# Auth Step4
headers = {
**defaultHeaders,
"Content-Type": "application/x-www-form-urlencoded",
}
# Fetch OAUTH token stage 1

data = {
"client_id": "9fb503e0-715b-47e8-adfd-ad4b7770f73b",
"grant_type": "authorization_code",
"redirect_uri": 'fordapp://userauthorized',
"grant_id": grant_id,
"code": code,
"code_verifier": code1
}

r = session.post(
"https://sso.ci.ford.com/oidc/endpoint/default/token",
data=data,
headers = headers,
data = data

)


if r.status_code == 200:
result = r.json()
if result["access_token"]:
access_token = result["access_token"]
else:
r.raise_for_status()


# Auth Step5
data = {"ciToken": access_token}
headers = {**apiHeaders, "Application-Id": self.region}
r = session.post(
"https://api.mps.ford.com/api/token/v2/cat-with-ci-access-token",
data=json.dumps(data),
headers=headers,
)

if r.status_code == 200:
_LOGGER.debug("Succesfully fetched token Stage1")
result = r.json()
data = {"ciToken": result["access_token"]}
headers = {**apiHeaders, "Application-Id": self.region}
# Fetch OAUTH token stage 2 and refresh token
r = session.post(
"https://api.mps.ford.com/api/token/v2/cat-with-ci-access-token",
data=json.dumps(data),
headers=headers,
)
if r.status_code == 200:
result = r.json()
self.token = result["access_token"]
self.refresh_token = result["refresh_token"]
self.expiresAt = time.time() + result["expires_in"]
if self.saveToken:
result["expiry_date"] = time.time() + result["expires_in"]
self.writeToken(result)
return True

self.token = result["access_token"]
self.refresh_token = result["refresh_token"]
self.expiresAt = time.time() + result["expires_in"]
if self.saveToken:
result["expiry_date"] = time.time() + result["expires_in"]
self.writeToken(result)
session.cookies.clear()
return True
else:
r.raise_for_status()

Expand Down
2 changes: 1 addition & 1 deletion custom_components/fordpass/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"config_flow": true,
"documentation": "https://github.com/itchannel/fordpass-ha",
"issue_tracker": "https://github.com/itchannel/fordpass-ha/issues",
"version": "0.1.33",
"version": "0.1.34",
"requirements": ["dotted==0.1.8"],
"ssdp": [],
"zeroconf": [],
Expand Down
2 changes: 2 additions & 0 deletions info.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

# **Changelog**
## Version 1.34
- Change oauth flow for latest Fordpass changes
## Version 1.33
- Fix occasional hacs error due to git tag issue
## Version 1.32
Expand Down

0 comments on commit 681b085

Please sign in to comment.