Skip to content

Commit

Permalink
Add digest auth hack
Browse files Browse the repository at this point in the history
Temporary hack until issue upstream is fixed
encode/httpx#1467
  • Loading branch information
elupus committed Feb 16, 2021
1 parent ac8fff1 commit f858ddd
Showing 1 changed file with 32 additions and 3 deletions.
35 changes: 32 additions & 3 deletions haphilipsjs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, Optional, Tuple, TypeVar, Union, cast
from typing import Any, Dict, Optional, Tuple, TypeVar, Union, cast, Generator
import httpx
import logging
import warnings
Expand Down Expand Up @@ -92,6 +92,35 @@ def __init__(self, data):

T = TypeVar('T')


class DigestAuthCached(httpx.DigestAuth):
# Temporary digest fix until https://github.com/encode/httpx/issues/1467 is resolved
_challenge = None

def auth_flow(self, request: httpx.Request) -> Generator[httpx.Request, httpx.Response, None]:
if self._challenge:
request.headers["Authorization"] = self._build_auth_header(request, self._challenge)

response = yield request

if response.status_code != 401 or "www-authenticate" not in response.headers:
# If the response is not a 401 then we don't
# need to build an authenticated request.
return

for auth_header in response.headers.get_list("www-authenticate"):
if auth_header.lower().startswith("digest "):
break
else:
# If the response does not include a 'WWW-Authenticate: Digest ...'
# header, then we don't need to build an authenticated request.
return

self._challenge = self._parse_challenge(request, response, auth_header)
request.headers["Authorization"] = self._build_auth_header(request, self._challenge)
yield request


class PhilipsTV(object):

def __init__(self, host=None, api_version=DEFAULT_API_VERSION, secured_transport=None, username=None, password=None, verify=False, auth_shared_key=None):
Expand Down Expand Up @@ -138,7 +167,7 @@ def __init__(self, host=None, api_version=DEFAULT_API_VERSION, secured_transport
self.session.headers["Accept"] = "application/json"

if username and password:
self.session.auth = httpx.DigestAuth(username, password)
self.session.auth = DigestAuthCached(username, password)

@property
def quirk_playpause_spacebar(self):
Expand Down Expand Up @@ -333,7 +362,7 @@ async def pairRequest(self, app_id: str, app_name: str, device_name: str, device

async def pairGrant(self, state: Dict[str, Any], pin: str):
"""Finish a pairing sequence"""
auth_handler = httpx.DigestAuth(
auth_handler = DigestAuthCached(
state["device"]["id"],
state["auth_key"]
)
Expand Down

0 comments on commit f858ddd

Please sign in to comment.