Skip to content

Commit

Permalink
feat: add mfa support
Browse files Browse the repository at this point in the history
This is untested but is based on a working example.
timdorr/tesla-api#258
  • Loading branch information
alandtse committed Feb 20, 2021
1 parent 56704b8 commit 413b585
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 7 deletions.
75 changes: 70 additions & 5 deletions teslajsonpy/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,14 @@ async def _process_messages() -> None:
# }
# )

async def get_authorization_code(self, email, password) -> Text:
async def get_authorization_code(
self,
email: Text,
password: Text,
mfa_code: Text = "",
mfa_device: int = 0,
retry_limit: int = 3,
) -> Text:
"""Get authorization code from the oauth3 login method."""
# https://tesla-api.timdorr.com/api-basics/authentication#step-2-obtain-an-authorization-code
if not (email and password):
Expand All @@ -378,10 +385,68 @@ async def get_authorization_code(self, email, password) -> Text:
html = await resp.text()
soup: BeautifulSoup = BeautifulSoup(html, "html.parser")
data = get_inputs(soup)
data["identity"] = self.email
data["credential"] = self.password
resp = await self.websession.post(url, data=data)
_process_resp(resp)
data["identity"] = email
data["credential"] = password
transaction_id: Text = data.get("transaction_id")
for attempt in range(retry_limit):
_LOGGER.debug("Attempt #%s", attempt)
resp = await self.websession.post(url, data=data)
_process_resp(resp)
if not resp.history:
html = await resp.text()
if "/mfa/verify" in html:
mfa_resp = await self.websession.get(
"https://auth.tesla.com/oauth2/v3/authorize/mfa/factors",
params={"transaction_id": transaction_id},
)
_process_resp(mfa_resp)
# {
# "data": [
# {
# "dispatchRequired": false,
# "id": "X-4Y-44e4-b9a4-54e114a13c40",
# "name": "Pixel",
# "factorType": "token:software",
# "factorProvider": "TESLA",
# "securityLevel": 1,
# "activatedAt": "2021-02-10T23:53:40.000Z",
# "updatedAt": "2021-02-10T23:54:20.000Z"
# }
# ]
# }
mfa_json = await mfa_resp.json()
if len(mfa_json.get("data", [])) > 1:
factor_id = mfa_json["data"][mfa_device]["id"]
if not mfa_code:
_LOGGER.debug("No MFA provided")
_LOGGER.debug("MFA Devices: %s", mfa_json["data"])
raise IncompleteCredentials(
"MFA Code missing", devices=mfa_json["data"]
)
mfa_resp = await self.websession.post(
"https://auth.tesla.com/oauth2/v3/authorize/mfa/verify",
json={
"transaction_id": transaction_id,
"factor_id": factor_id,
"passcode": mfa_code,
},
)
_process_resp(mfa_resp)
mfa_json = await mfa_resp.json()
if not (
mfa_json["data"].get("approved")
and mfa_json["data"].get("valid")
):
_LOGGER.debug("MFA Code invalid")
raise IncompleteCredentials(
"MFA Code invalid", devices=mfa_json["data"]
)
resp = await self.websession.post(url, data=data)
_process_resp(resp)
await asyncio.sleep(3)
if not (resp.history):
_LOGGER.debug("Failed to authenticate")
raise IncompleteCredentials("Unable to login with credentials")
code_url = URL(resp.history[-1].url)
return code_url.query.get("code")

Expand Down
8 changes: 6 additions & 2 deletions teslajsonpy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
https://github.com/zabuldon/teslajsonpy
"""
import logging
from typing import Any, Dict, Text

_LOGGER = logging.getLogger(__name__)


class TeslaException(Exception):
"""Class of Tesla API exceptions."""

def __init__(self, code, *args, **kwargs):
def __init__(self, code: Text, *args, **kwargs):
"""Initialize exceptions for the Tesla API."""
self.message = ""
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -52,7 +53,10 @@ class RetryLimitError(TeslaException):
class IncompleteCredentials(TeslaException):
"""Class of exceptions for incomplete credentials."""

pass
def __init__(self, code: Text, *args, devices: Dict[Any, Any] = None, **kwargs):
"""Initialize exception to include list of devices."""
super().__init__(code, *args, **kwargs)
self.devices = devices or {}


class UnknownPresetMode(TeslaException):
Expand Down

0 comments on commit 413b585

Please sign in to comment.