Skip to content

Commit

Permalink
1. adjust email_validator for the new version (disable call for dns q… (
Browse files Browse the repository at this point in the history
#65)

* 1. adjust email_validator for the new version 1.3.0 (disable call for dns queries). 2. adjust the tests for method that changed from get to post

* fix definition of argument (list[str]) to be compatible with python 3.7, 3.8

* set allow_redirect=False to all Post calls
  • Loading branch information
guyp-descope committed Oct 21, 2022
1 parent 44620c3 commit 0554936
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 37 deletions.
5 changes: 3 additions & 2 deletions descope/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def do_post(self, uri: str, body: dict, pswd: str = None) -> requests.Response:
f"{self.base_url}{uri}",
headers=self._get_default_headers(pswd),
data=json.dumps(body),
allow_redirects=False,
verify=self.secure,
)
if not response.ok:
Expand Down Expand Up @@ -129,7 +130,7 @@ def verify_delivery_method(
if not user.get("email", None):
user["email"] = identifier
try:
validate_email(user["email"])
validate_email(email=user["email"], check_deliverability=False)
return True
except EmailNotValidError:
return False
Expand Down Expand Up @@ -190,7 +191,7 @@ def validate_email(email: str):
)

try:
validate_email(email)
validate_email(email=email, check_deliverability=False)
except EmailNotValidError as ex:
raise AuthException(
400, ERROR_TYPE_INVALID_ARGUMENT, f"Invalid email address: {ex}"
Expand Down
18 changes: 10 additions & 8 deletions descope/descope_client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

import requests

from descope.auth import Auth # noqa: F401
Expand Down Expand Up @@ -53,21 +55,21 @@ def saml(self):
def webauthn(self):
return self._webauthn

def validate_permissions(self, jwt_response: dict, permissions: list[str]) -> bool:
def validate_permissions(self, jwt_response: dict, permissions: List[str]) -> bool:
"""
Validate that a jwt_response has been granted the specified permissions.
For a multi-tenant environment use validate_tenant_permissions function
Args:
jwt_response (dict): The jwt_response object which includes all JWT claims information
permissions (list[str]): List of permissions to validate for this jwt_response
permissions (List[str]): List of permissions to validate for this jwt_response
Return value (bool): returns true if all permissions granted; false if at least one permission not granted
"""
return self.validate_tenant_permissions(jwt_response, "", permissions)

def validate_tenant_permissions(
self, jwt_response: dict, tenant: str, permissions: list[str]
self, jwt_response: dict, tenant: str, permissions: List[str]
) -> bool:
"""
Validate that a jwt_response has been granted the specified permissions on the specified tenant.
Expand All @@ -76,7 +78,7 @@ def validate_tenant_permissions(
Args:
jwt_response (dict): The jwt_response object which includes all JWT claims information
tenant (str): TenantId
permissions (list[str]): List of permissions to validate for this jwt_response
permissions (List[str]): List of permissions to validate for this jwt_response
Return value (bool): returns true if all permissions granted; false if at least one permission not granted
"""
Expand All @@ -99,21 +101,21 @@ def validate_tenant_permissions(
return False
return True

def validate_roles(self, jwt_response: dict, roles: list[str]) -> bool:
def validate_roles(self, jwt_response: dict, roles: List[str]) -> bool:
"""
Validate that a jwt_response has been granted the specified roles.
For a multi-tenant environment use validate_tenant_roles function
Args:
jwt_response (dict): The jwt_response object which includes all JWT claims information
roles (list[str]): List of roles to validate for this jwt_response
roles (List[str]): List of roles to validate for this jwt_response
Return value (bool): returns true if all roles granted; false if at least one role not granted
"""
return self.validate_tenant_roles(jwt_response, "", roles)

def validate_tenant_roles(
self, jwt_response: dict, tenant: str, roles: list[str]
self, jwt_response: dict, tenant: str, roles: List[str]
) -> bool:
"""
Validate that a jwt_response has been granted the specified roles on the specified tenant.
Expand All @@ -122,7 +124,7 @@ def validate_tenant_roles(
Args:
jwt_response (dict): The jwt_response object which includes all JWT claims information
tenant (str): TenantId
roles (list[str]): List of roles to validate for this jwt_response
roles (List[str]): List of roles to validate for this jwt_response
Return value (bool): returns true if all roles granted; false if at least one role not granted
"""
Expand Down
2 changes: 1 addition & 1 deletion liccheck.ini
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ unauthorized_licenses:
# Apache-2.0 license
coverage: 6.3.3
# CC0 1.0 Universal (CC0 1.0) Public Domain Dedication license
email-validator: 1.2.1
email-validator: 1.3.0
#Public Domain (filelock package is dependency of filelock << virtualenv << pre-commit)
filelock:>=3.4.1
#Mozilla Public License 2.0 (MPL 2.0) (certifi package is dependency of requests
Expand Down
20 changes: 10 additions & 10 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ cryptography==38.0.1 ; python_version >= "3.7" and python_version < "4.0" \
dnspython==2.2.1 ; python_version >= "3.7" and python_version < "4.0" \
--hash=sha256:0f7569a4a6ff151958b64304071d370daa3243d15941a7beedf0c9fe5105603e \
--hash=sha256:a851e51367fb93e9e1361732c1d60dab63eff98712e503ea7d92e6eccb109b4f
email-validator==1.3.0; python_version >= "3.7" and python_version < "4.0" \
email-validator==1.3.0 ; python_version >= "3.7" and python_version < "4.0" \
--hash=sha256:553a66f8be2ec2dea641ae1d3f29017ab89e9d603d4a25cdaac39eefa283d769 \
--hash=sha256:816073f2a7cffef786b29928f58ec16cdac42710a53bb18aa94317e3e145ec5c
idna==3.4 ; python_version >= "3.7" and python_version < "4" \
Expand All @@ -108,7 +108,7 @@ idna==3.4 ; python_version >= "3.7" and python_version < "4" \
pycparser==2.21 ; python_version >= "3.7" and python_version < "4.0" \
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
PyJWT==2.5.0; python_version >= "3.7" and python_version < "4.0" \
pyjwt==2.5.0 ; python_version >= "3.7" and python_version < "4.0" \
--hash=sha256:8d82e7087868e94dd8d7d418e5088ce64f7daab4b36db654cbaedb46f9d1ca80 \
--hash=sha256:e77ab89480905d86998442ac5788f35333fa85f65047a534adc38edf3c88fc3b
requests==2.28.1 ; python_version >= "3.7" and python_version < "4" \
Expand Down
4 changes: 2 additions & 2 deletions tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def test_refresh_token(self):
auth = Auth(self.dummy_project_id, self.public_key_dict)

# Test fail flow
with patch("requests.get") as mock_request:
with patch("requests.post") as mock_request:
mock_request.return_value.ok = False
self.assertRaises(
AuthException,
Expand All @@ -244,7 +244,7 @@ def test_exchange_access_key(self):
auth = Auth(self.dummy_project_id, self.public_key_dict)

# Test fail flow
with patch("requests.get") as mock_request:
with patch("requests.post") as mock_request:
mock_request.return_value.ok = False
self.assertRaises(
AuthException,
Expand Down
20 changes: 10 additions & 10 deletions tests/test_descope_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ def test_logout(self):
self.assertRaises(AuthException, client.logout, None)

# Test failed flow
with patch("requests.get") as mock_get:
mock_get.return_value.ok = False
with patch("requests.post") as mock_post:
mock_post.return_value.ok = False
self.assertRaises(AuthException, client.logout, dummy_refresh_token)

# Test success flow
with patch("requests.get") as mock_get:
mock_get.return_value.ok = True
with patch("requests.post") as mock_post:
mock_post.return_value.ok = True
self.assertIsNotNone(client.logout(dummy_refresh_token))

def test_me(self):
Expand Down Expand Up @@ -273,7 +273,7 @@ def test_expired_token(self):
new_session_token = "eyJhbGciOiJFUzM4NCIsImtpZCI6IlAyQ3VDOXl2MlVHdEdJMW84NGdDWkViOXFFUVciLCJ0eXAiOiJKV1QifQ.eyJkcm4iOiJEUyIsImV4cCI6MjQ5MzA2MTQxNSwiaWF0IjoxNjU5NjQzMDYxLCJpc3MiOiJQMkN1Qzl5djJVR3RHSTFvODRnQ1pFYjlxRVFXIiwic3ViIjoiVTJDdUNQdUpnUFdIR0I1UDRHbWZidVBHaEdWbSJ9.gMalOv1GhqYVsfITcOc7Jv_fibX1Iof6AFy2KCVmyHmU2KwATT6XYXsHjBFFLq262Pg-LS1IX9f_DV3ppzvb1pSY4ccsP6WDGd1vJpjp3wFBP9Sji6WXL0SCCJUFIyJR"
valid_refresh_token = "eyJhbGciOiJFUzM4NCIsImtpZCI6IlAyQ3VDOXl2MlVHdEdJMW84NGdDWkViOXFFUVciLCJ0eXAiOiJKV1QifQ.eyJkcm4iOiJEU1IiLCJleHAiOjIyNjQ0NDMwNjEsImlhdCI6MTY1OTY0MzA2MSwiaXNzIjoiUDJDdUM5eXYyVUd0R0kxbzg0Z0NaRWI5cUVRVyIsInN1YiI6IlUyQ3VDUHVKZ1BXSEdCNVA0R21mYnVQR2hHVm0ifQ.mRo9FihYMR3qnQT06Mj3CJ5X0uTCEcXASZqfLLUv0cPCLBtBqYTbuK-ZRDnV4e4N6zGCNX2a3jjpbyqbViOxICCNSxJsVb-sdsSujtEXwVMsTTLnpWmNsMbOUiKmoME0"
expired_token = "eyJhbGciOiJFUzM4NCIsImtpZCI6IlAyQ3VDOXl2MlVHdEdJMW84NGdDWkViOXFFUVciLCJ0eXAiOiJKV1QifQ.eyJkcm4iOiJEUyIsImV4cCI6MTY1OTY0NDI5OCwiaWF0IjoxNjU5NjQ0Mjk3LCJpc3MiOiJQMkN1Qzl5djJVR3RHSTFvODRnQ1pFYjlxRVFXIiwic3ViIjoiVTJDdUNQdUpnUFdIR0I1UDRHbWZidVBHaEdWbSJ9.wBuOnIQI_z3SXOszqsWCg8ilOPdE5ruWYHA3jkaeQ3uX9hWgCTd69paFajc-xdMYbqlIF7JHji7T9oVmkCUJvDNgRZRZO9boMFANPyXitLOK4aX3VZpMJBpFxdrWV3GE"
with patch("requests.get") as mock_request:
with patch("requests.post") as mock_request:
my_mock_response = mock.Mock()
my_mock_response.ok = True
my_mock_response.json.return_value = {"sessionJwt": new_session_token}
Expand Down Expand Up @@ -363,7 +363,7 @@ def test_validate_permissions(self):
client.validate_tenant_permissions(jwt_response, "t1", ["Perm 2"])
)

jwt_response = {"tenants": {"t1": {"roles": "Perm 1"}}}
jwt_response = {"tenants": {"t1": {"permissions": "Perm 1"}}}
self.assertTrue(
client.validate_tenant_permissions(jwt_response, "t1", ["Perm 1"])
)
Expand Down Expand Up @@ -395,11 +395,11 @@ def test_validate_roles(self):
jwt_response = {"tenants": {"t1": {}}}
self.assertFalse(client.validate_tenant_roles(jwt_response, "t1", ["Perm 2"]))

jwt_response = {"tenants": {"t1": {"roles": "Perm 1"}}}
self.assertTrue(client.validate_tenant_roles(jwt_response, "t1", ["Perm 1"]))
self.assertFalse(client.validate_tenant_roles(jwt_response, "t1", ["Perm 2"]))
jwt_response = {"tenants": {"t1": {"roles": "Role 1"}}}
self.assertTrue(client.validate_tenant_roles(jwt_response, "t1", ["Role 1"]))
self.assertFalse(client.validate_tenant_roles(jwt_response, "t1", ["Role 2"]))
self.assertFalse(
client.validate_tenant_roles(jwt_response, "t1", ["Perm 1", "Perm 2"])
client.validate_tenant_roles(jwt_response, "t1", ["Role 1", "Role 2"])
)


Expand Down
3 changes: 3 additions & 0 deletions tests/test_magiclink.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ def test_sign_in_cross_device(self):
"crossDevice": True,
}
),
allow_redirects=False,
verify=True,
)
self.assertEqual(res["pendingRef"], "aaaa")
Expand Down Expand Up @@ -291,6 +292,7 @@ def test_sign_up_cross_device(self):
"email": "[email protected]",
}
),
allow_redirects=False,
verify=True,
)
self.assertEqual(res["pendingRef"], "aaaa")
Expand Down Expand Up @@ -321,6 +323,7 @@ def test_sign_up_or_in_cross_device(self):
"crossDevice": True,
}
),
allow_redirects=False,
verify=True,
)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def test_oauth_start(self):
)

def test_compose_exchange_params(self):
self.assertEqual(Auth._compose_exchange_params("c1"), {"code": "c1"})
self.assertEqual(Auth._compose_exchange_body("c1"), {"code": "c1"})

def test_exchange_token(self):
oauth = OAuth(Auth(self.dummy_project_id, self.public_key_dict))
Expand Down
2 changes: 1 addition & 1 deletion tests/test_saml.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_saml_start(self):
)

def test_compose_exchange_params(self):
self.assertEqual(Auth._compose_exchange_params("c1"), {"code": "c1"})
self.assertEqual(Auth._compose_exchange_body("c1"), {"code": "c1"})

def test_exchange_token(self):
saml = SAML(Auth(self.dummy_project_id, self.public_key_dict))
Expand Down
1 change: 1 addition & 0 deletions tests/test_totp.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def test_update_user(self):
"Authorization": f"Bearer {self.dummy_project_id}:{valid_jwt_token}",
},
data=json.dumps({"externalId": "[email protected]"}),
allow_redirects=False,
verify=True,
)
self.assertEqual(res, valid_response)
6 changes: 6 additions & 0 deletions tests/test_webauthn.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def test_sign_up_start(self):
data=json.dumps(
{"user": {"externalId": "id1"}, "origin": "https://example.com"}
),
allow_redirects=False,
verify=True,
)
self.assertEqual(res, valid_response)
Expand Down Expand Up @@ -145,6 +146,7 @@ def test_sign_up_finish(self):
"Authorization": f"Bearer {self.dummy_project_id}",
},
data=json.dumps({"transactionId": "t01", "response": "response01"}),
allow_redirects=False,
verify=True,
)
self.assertIsNotNone(webauthn.sign_up_finish("t01", "response01"))
Expand Down Expand Up @@ -191,6 +193,7 @@ def test_sign_in_start(self):
"Authorization": f"Bearer {self.dummy_project_id}",
},
data=json.dumps({"externalId": "id1", "origin": "https://example.com"}),
allow_redirects=False,
verify=True,
)
self.assertEqual(res, valid_response),
Expand Down Expand Up @@ -230,6 +233,7 @@ def test_sign_in_finish(self):
"Authorization": f"Bearer {self.dummy_project_id}",
},
data=json.dumps({"transactionId": "t01", "response": "response01"}),
allow_redirects=False,
verify=True,
)
self.assertIsNotNone(webauthn.sign_up_finish("t01", "response01"))
Expand Down Expand Up @@ -298,6 +302,7 @@ def test_update_start(self):
data=json.dumps(
{"externalId": "[email protected]", "origin": "https://example.com"}
),
allow_redirects=False,
verify=True,
)
self.assertEqual(res, valid_response)
Expand Down Expand Up @@ -336,6 +341,7 @@ def test_update_finish(self):
"Authorization": f"Bearer {self.dummy_project_id}",
},
data=json.dumps({"transactionId": "t01", "response": "response01"}),
allow_redirects=False,
verify=True,
)
self.assertIsNotNone(webauthn.sign_up_finish("t01", "response01"))
Expand Down

0 comments on commit 0554936

Please sign in to comment.