From b527015bbe70efaef65ddb50a29f44c78f7a7c86 Mon Sep 17 00:00:00 2001 From: Steven Clouston Date: Thu, 11 Jul 2024 17:30:18 +1200 Subject: [PATCH] Delegate validate challenge logic to backend --- authsignal/client.py | 45 ++++++++++++++++++++++--------------------- authsignal/version.py | 2 +- pyproject.toml | 2 +- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/authsignal/client.py b/authsignal/client.py index 74beb48..bce78d8 100644 --- a/authsignal/client.py +++ b/authsignal/client.py @@ -3,11 +3,14 @@ from authsignal.version import VERSION import humps +from typing import Dict, Any, Optional import json import requests + _UNICODE_STRING = str API_BASE_URL = 'https://signal.authsignal.com' +API_CHALLENGE_URL = 'https://api.authsignal.com/v1' BLOCK = "BLOCK" ALLOW = "ALLOW" @@ -175,31 +178,29 @@ def enroll_verified_authenticator(self, user_id, authenticator_payload, path=No except requests.exceptions.RequestException as e: raise ApiException(str(e), path) from e - def validate_challenge(self, token, user_id=None): - try: - decoded_token = jwt.decode(token, self.api_key, algorithms=["HS256"], options={'verify_aud': False}) - - except jwt.DecodeError as e: - print(e) - return - - decoded_user_id = decoded_token["other"]["userId"] - action = decoded_token["other"]["actionCode"] - idempotency_key = decoded_token["other"]["idempotencyKey"] + def validate_challenge(self, token: str, user_id: Optional[str] = None) -> Dict[str, Any]: + path = f"{API_CHALLENGE_URL}/validate" + headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + } - if user_id and user_id != decoded_user_id: - return {"user_id": decoded_user_id, "success": False, "state": None} - - if action and idempotency_key: - action_result = self.get_action(user_id=decoded_user_id, action=action, idempotency_key=idempotency_key) - - if action_result: - state = action_result["state"] - success = state == "CHALLENGE_SUCCEEDED" + try: + response = self.session.post( + path, + auth=requests.auth.HTTPBasicAuth(self.api_key, ''), + data=json.dumps({'token': token, 'userId': user_id}), + headers=headers, + timeout=self.timeout + ) + + response_data = humps.decamelize(response.json()) - return {"user_id": decoded_user_id, "success": success, "state": state, "action": action} + action = response_data.pop('action_code', None) - return {"userId": decoded_user_id, "success": False, "state": None} + return {'action': action, **response_data} + except requests.exceptions.RequestException as e: + raise ApiException(str(e), path) from e def _default_headers(self): return {'Content-type': 'application/json', diff --git a/authsignal/version.py b/authsignal/version.py index 52d4c97..47f23af 100644 --- a/authsignal/version.py +++ b/authsignal/version.py @@ -1 +1 @@ -VERSION = '1.0.4' \ No newline at end of file +VERSION = '2.0.0' \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 96d68f2..0fb4ef7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "authsignal" -version = "1.0.4" +version = "2.0.0" description = "Authsignal Python SDK for Passwordless Step Up Authentication" authors = ["justinsoong "] license = "MIT"