Added ability to have multiple backup api endpoints for logging in

This commit is contained in:
Kevin Fronczak
2019-03-01 16:03:22 -05:00
parent 9dda477e3d
commit d8bac39c52
3 changed files with 58 additions and 37 deletions
+41 -28
View File
@@ -29,7 +29,7 @@ from blinkpy.helpers.util import (
create_session, merge_dicts, get_time, BlinkURLHandler,
BlinkAuthenticationException)
from blinkpy.helpers.constants import (
BLINK_URL, LOGIN_URL, LOGIN_BACKUP_URL)
BLINK_URL, LOGIN_URL, OLD_LOGIN_URL, LOGIN_BACKUP_URL)
from blinkpy.helpers.constants import __version__
REFRESH_RATE = 30
@@ -119,33 +119,12 @@ class Blink():
if not isinstance(self._password, str):
raise BlinkAuthenticationException(ERROR.PASSWORD)
login_url = LOGIN_URL
response = api.request_login(self,
login_url,
self._username,
self._password,
is_retry=is_retry)
try:
if response.status_code != 200:
_LOGGER.debug("Received response code %s during login.",
response.status_code)
login_url = LOGIN_BACKUP_URL
response = api.request_login(self,
login_url,
self._username,
self._password,
is_retry=is_retry)
response = response.json()
(self.region_id, self.region), = response['region'].items()
except AttributeError:
_LOGGER.error("Login API endpoint failed with response %s",
response,
exc_info=True)
login_urls = [LOGIN_URL, OLD_LOGIN_URL, LOGIN_BACKUP_URL]
response = self.login_request(login_urls, is_retry=is_retry)
if not response:
return False
except KeyError:
_LOGGER.warning("Could not extract region info.")
self.region_id = 'piri'
self.region = 'UNKNOWN'
self._host = "{}.{}".format(self.region_id, BLINK_URL)
self._token = response['authtoken']['authtoken']
@@ -154,10 +133,44 @@ class Blink():
self._auth_header = {'Host': self._host,
'TOKEN_AUTH': self._token}
self.urls = BlinkURLHandler(self.region_id)
self._login_url = login_url
return self._auth_header
def login_request(self, login_urls, is_retry=False):
"""Make a login request."""
try:
login_url = login_urls.pop(0)
except IndexError:
_LOGGER.error("Could not login to blink servers.")
return False
_LOGGER.info("Attempting login with %s", login_url)
response = api.request_login(self,
login_url,
self._username,
self._password,
is_retry=is_retry)
try:
if response.status_code != 200:
response = self.login_request(login_urls)
response = response.json()
(self.region_id, self.region), = response['region'].items()
except AttributeError:
_LOGGER.error("Login API endpoint failed with response %s",
response,
exc_info=True)
return False
except KeyError:
_LOGGER.warning("Could not extract region info.")
self.region_id = 'piri'
self.region = 'UNKNOWN'
self._login_url = login_url
return response
def get_ids(self):
"""Set the network ID and Account ID."""
response = api.request_networks(self)
+2 -1
View File
@@ -47,7 +47,8 @@ URLS
BLINK_URL = 'immedia-semi.com'
DEFAULT_URL = "{}.{}".format('prod', BLINK_URL)
BASE_URL = "https://{}".format(DEFAULT_URL)
LOGIN_URL = "{}/login".format(BASE_URL)
LOGIN_URL = "{}/api/v2/login".format(BASE_URL)
OLD_LOGIN_URL = "{}/login".format(BASE_URL)
LOGIN_BACKUP_URL = "https://{}.{}/login".format('rest.piri', BLINK_URL)
'''
+15 -8
View File
@@ -2,7 +2,6 @@
import unittest
from unittest import mock
import logging
from requests import Request
from blinkpy import blinkpy
from blinkpy.sync_module import BlinkSyncModule
@@ -56,24 +55,32 @@ class TestBlinkFunctions(unittest.TestCase):
"""Clean up after test."""
self.blink = None
@mock.patch('blinkpy.blinkpy.api.http_req')
@mock.patch('blinkpy.blinkpy.api.request_login')
def test_backup_url(self, req, mock_sess):
"""Test backup login method."""
fake_req = Request('POST', 'http://wrong.url').prepare()
json_resp = {
'authtoken': {'authtoken': 'foobar123'},
'networks': {'1234': {'name': 'foobar', 'onboarded': True}}
}
bad_req = mresp.MockResponse({}, 404)
new_req = mresp.MockResponse(json_resp, 200)
req.side_effect = [
mresp.mocked_session_send(fake_req),
bad_req,
bad_req,
new_req
]
self.blink.get_auth_token()
self.assertEqual(self.blink.region_id, 'piri')
self.assertEqual(self.blink.region, 'UNKNOWN')
self.blink.login_request(['test1', 'test2', 'test3'])
# pylint: disable=protected-access
self.assertEqual(self.blink._token, 'foobar123')
self.assertEqual(self.blink._login_url, 'test3')
req.side_effect = [
bad_req,
new_req,
bad_req
]
self.blink.login_request(['test1', 'test2', 'test3'])
# pylint: disable=protected-access
self.assertEqual(self.blink._login_url, 'test2')
def test_merge_cameras(self, mock_sess):
"""Test merge camera functionality."""