aiokwikset 0.2.1__tar.gz → 0.2.2a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of aiokwikset might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aiokwikset
3
- Version: 0.2.1
3
+ Version: 0.2.2a1
4
4
  Summary: Python interface for Kwikset Smart Locks
5
5
  Home-page: https://github.com/explosivo22/aiokwikset
6
6
  Author: Brad Barbour
@@ -1,5 +1,6 @@
1
1
  import json
2
2
  import aioboto3
3
+ import botocore.exceptions
3
4
  import attr
4
5
  import datetime
5
6
 
@@ -17,7 +18,7 @@ from aiohttp.client_exceptions import (
17
18
  ClientPayloadError
18
19
  )
19
20
 
20
- from .errors import RequestError
21
+ from .errors import RequestError, NotAuthorized
21
22
  from .device import Device
22
23
  from .user import User
23
24
  from .exceptions import TokenVerificationException
@@ -169,7 +170,7 @@ class API(object):
169
170
  if not self.access_token:
170
171
  raise AttributeError('Access Token Required to Check Token')
171
172
  now = datetime.datetime.now()
172
- dec_access_token = jwt.get_unverified_claims(self.access_token)
173
+ dec_access_token = jwt.get_unverified_claims(self.id_token)
173
174
 
174
175
  if now > datetime.datetime.fromtimestamp(dec_access_token['exp']):
175
176
  expired = True
@@ -185,12 +186,13 @@ class API(object):
185
186
  """
186
187
  auth_params = {'SECRET_HASH': '', 'REFRESH_TOKEN': self.refresh_token}
187
188
 
188
- async with self.get_client() as client:
189
- refresh_response = await client.initiate_auth(
190
- ClientId=self.client_id,
191
- AuthFlow='REFRESH_TOKEN_AUTH',
192
- AuthParameters=auth_params,
193
- )
189
+ try:
190
+ async with self.get_client() as client:
191
+ refresh_response = await client.initiate_auth(
192
+ ClientId=self.client_id,
193
+ AuthFlow='REFRESH_TOKEN_AUTH',
194
+ AuthParameters=auth_params,
195
+ )
194
196
 
195
197
  self._set_attributes(
196
198
  refresh_response,
@@ -209,6 +211,11 @@ class API(object):
209
211
 
210
212
  if not self.user:
211
213
  self.user = User(self._request)
214
+
215
+ #attempt to catch the NotAuthorizedException
216
+ except botocore.exceptions.ClientError as err:
217
+ if err.response['Error']['Code'] == 'NotAuthorizedException':
218
+ raise NotAuthorized("Refresh Token has been revoked.")
212
219
 
213
220
  def _set_attributes(self, response, attribute_dict):
214
221
  """
@@ -239,6 +246,26 @@ class API(object):
239
246
  self.code_type = code_type
240
247
 
241
248
  pre_verification = await self.aws.authenticate_user()
249
+
250
+ if pre_verification.get('AuthenticationResult'):
251
+ print("2-step verification disabled")
252
+ await self.verify_token(pre_verification['AuthenticationResult']['IdToken'],
253
+ 'id_token', 'id')
254
+ self.refresh_token = pre_verification['AuthenticationResult']['RefreshToken']
255
+ await self.verify_token(pre_verification['AuthenticationResult']['AccessToken'],
256
+ 'access_token', 'access')
257
+ self.token_type = pre_verification['AuthenticationResult']['TokenType']
258
+
259
+ if not self.device:
260
+ self.device = Device(self._request)
261
+
262
+ if not self.user:
263
+ self.user = User(self._request)
264
+
265
+ return
266
+
267
+ print("2-step verification enabled")
268
+
242
269
  return pre_verification
243
270
 
244
271
  async def verify_user(self, pre_verification, code):
@@ -6,9 +6,12 @@ import hmac
6
6
  import re
7
7
 
8
8
  import aioboto3
9
+ import botocore.exceptions
9
10
  import os
10
11
  import six
11
12
 
13
+ from .errors import NotAuthorized
14
+
12
15
  # https://github.com/aws/amazon-cognito-identity-js/blob/master/src/AuthenticationHelper.js#L22
13
16
  n_hex = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' + \
14
17
  '29024E088A67CC74020BBEA63B139B22514A08798E3404DD' + \
@@ -240,35 +243,44 @@ class AWSKWIKSET(object):
240
243
  boto_client = self.client or client
241
244
  auth_params = self.get_auth_params()
242
245
 
243
- async with boto_client as client:
244
- response = await client.initiate_auth(
245
- AuthFlow='CUSTOM_AUTH',
246
- AuthParameters=auth_params,
247
- ClientId=self.client_id
248
- )
249
- if response['ChallengeName'] == self.PASSWORD_VERIFIER_CHALLENGE:
250
- challenge_response = self.process_challenge(
251
- response['ChallengeParameters'])
252
-
253
- custom_challenge = await client.respond_to_auth_challenge(
254
- ClientId=self.client_id,
255
- ChallengeName=self.PASSWORD_VERIFIER_CHALLENGE,
256
- Session=response['Session'],
257
- ChallengeResponses=challenge_response)
258
-
259
- if custom_challenge['ChallengeName'] == self.CUSTOM_VERIFIER_CHALLENGE:
260
- custom_challenge_response = self.process_custom_challenge()
261
-
262
- custom_challenge_code = await client.respond_to_auth_challenge(
246
+ try:
247
+ async with boto_client as client:
248
+ response = await client.initiate_auth(
249
+ AuthFlow='CUSTOM_AUTH',
250
+ AuthParameters=auth_params,
251
+ ClientId=self.client_id
252
+ )
253
+ if response['ChallengeName'] == self.PASSWORD_VERIFIER_CHALLENGE:
254
+ challenge_response = self.process_challenge(
255
+ response['ChallengeParameters'])
256
+
257
+ custom_challenge = await client.respond_to_auth_challenge(
263
258
  ClientId=self.client_id,
264
- ChallengeName=self.CUSTOM_VERIFIER_CHALLENGE,
265
- Session=custom_challenge['Session'],
266
- ChallengeResponses=custom_challenge_response)
267
-
268
- return custom_challenge_code
259
+ ChallengeName=self.PASSWORD_VERIFIER_CHALLENGE,
260
+ Session=response['Session'],
261
+ ChallengeResponses=challenge_response)
262
+
263
+ #2-step verification is disabled
264
+ if custom_challenge.get('AuthenticationResult'):
265
+ return custom_challenge
266
+
267
+ #2-step verification is enabled
268
+ if custom_challenge['ChallengeName'] == self.CUSTOM_VERIFIER_CHALLENGE:
269
+ custom_challenge_response = self.process_custom_challenge()
270
+
271
+ custom_challenge_code = await client.respond_to_auth_challenge(
272
+ ClientId=self.client_id,
273
+ ChallengeName=self.CUSTOM_VERIFIER_CHALLENGE,
274
+ Session=custom_challenge['Session'],
275
+ ChallengeResponses=custom_challenge_response)
276
+
277
+ return custom_challenge_code
278
+ else:
279
+ raise NotImplementedError('The %s challenge is not supported'
280
+ % response['ChallengeName'])
269
281
  else:
270
282
  raise NotImplementedError('The %s challenge is not supported'
271
- % response['ChallengeName'])
272
- else:
273
- raise NotImplementedError('The %s challenge is not supported'
274
- % response['ChallengeName'])
283
+ % response['ChallengeName'])
284
+ except botocore.exceptions.ClientError as err:
285
+ if err.response['Error']['Code'] == 'NotAuthorizedException':
286
+ raise NotAuthorized("Refresh Token has been revoked")
@@ -0,0 +1,19 @@
1
+ """Define package errors."""
2
+ from typing import Any
3
+
4
+ class KwiksetError(Exception):
5
+ """Define a base error."""
6
+
7
+ pass
8
+
9
+
10
+ class RequestError(KwiksetError):
11
+ """Define an error related to invalid requests."""
12
+
13
+ pass
14
+
15
+ class NotAuthorized(Exception):
16
+ """Raised when the refresh token has been revoked"""
17
+
18
+ def __init__(self, *args: Any) -> None:
19
+ Exception.__init__(self, *args)
@@ -1,3 +1,5 @@
1
+ from typing import Any
2
+
1
3
  class WarrantException(Exception):
2
4
  """Base class for all Warrant exceptions"""
3
5
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aiokwikset
3
- Version: 0.2.1
3
+ Version: 0.2.2a1
4
4
  Summary: Python interface for Kwikset Smart Locks
5
5
  Home-page: https://github.com/explosivo22/aiokwikset
6
6
  Author: Brad Barbour
@@ -13,7 +13,7 @@ except FileNotFoundError:
13
13
 
14
14
  setup(
15
15
  name="aiokwikset",
16
- version="0.2.1",
16
+ version="0.2.2a1",
17
17
  description="Python interface for Kwikset Smart Locks",
18
18
  long_description=long_description,
19
19
  long_description_content_type='text/markdown',
@@ -1,13 +0,0 @@
1
- """Define package errors."""
2
-
3
-
4
- class KwiksetError(Exception):
5
- """Define a base error."""
6
-
7
- pass
8
-
9
-
10
- class RequestError(KwiksetError):
11
- """Define an error related to invalid requests."""
12
-
13
- pass
File without changes
File without changes
File without changes