Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ This is the changelog for [Authress SDK](readme.md).

## 3.1 ##
* [Breaking] Throw validation error on setting a property that doesn't exist in any of the Authress DTO Models.
* Optimize JWKs fetching using the keyId

## 3.0 ##
* [Breaking] Added type checking everywhere - This means most models have breaking changes.
Expand Down
1 change: 1 addition & 0 deletions authress/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from authress.authress_client import AuthressClient
from authress.http_client import HttpClient
from authress.rest import ApiException
from authress.utils.service_client_token_provider import ServiceClientTokenProvider

# import apis into sdk package
from authress.api.access_records_api import AccessRecordsApi
Expand Down
3 changes: 0 additions & 3 deletions authress/api/access_records_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
from authress.models.access_request_response import AccessRequestResponse
from authress.models.claim_request import ClaimRequest

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -53,8 +52,6 @@ class AccessRecordsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/accounts_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
from authress.models.identity_collection import IdentityCollection
from authress.models.identity_request import IdentityRequest

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -53,8 +52,6 @@ class AccountsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/applications_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@

from authress.models.application_delegation import ApplicationDelegation

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -46,8 +45,6 @@ class ApplicationsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/connections_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
from authress.models.connection_collection import ConnectionCollection
from authress.models.user_connection_credentials import UserConnectionCredentials

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -48,8 +47,6 @@ class ConnectionsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/extensions_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
from authress.models.o_auth_token_request import OAuthTokenRequest
from authress.models.o_auth_token_response import OAuthTokenResponse

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -52,8 +51,6 @@ class ExtensionsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/groups_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from authress.models.group import Group
from authress.models.group_collection import GroupCollection

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -49,8 +48,6 @@ class GroupsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/invites_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
from authress.models.account import Account
from authress.models.invite import Invite

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -47,8 +46,6 @@ class InvitesApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/resource_permissions_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
from authress.models.permissioned_resource_collection import PermissionedResourceCollection
from authress.models.resource_users_collection import ResourceUsersCollection

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -50,8 +49,6 @@ class ResourcePermissionsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/roles_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from authress.models.role import Role
from authress.models.role_collection import RoleCollection

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -44,8 +43,6 @@ class RolesApi(object):
"""

def __init__(self, api_client=None) -> None:
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/service_clients_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
from authress.models.client_access_key import ClientAccessKey
from authress.models.client_collection import ClientCollection

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -50,8 +49,6 @@ class ServiceClientsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/tenants_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from authress.models.tenant_collection import TenantCollection
from authress.models.tenant_user import TenantUser

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -43,8 +42,6 @@ class TenantsApi:
"""

def __init__(self, api_client=None) -> None:
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
12 changes: 7 additions & 5 deletions authress/api/token_verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
from authress.utils import service_client_token_provider, PackageVersionProvider

class TokenVerifier(object):
def __init__(self):
def __init__(self, http_client=None):
self.http_client = http_client
if http_client is None:
self.http_client = rest.RESTClientObject()

self.keyMap = dict()
self.package_version_provider = PackageVersionProvider()

Expand Down Expand Up @@ -72,14 +76,12 @@ def get_public_key(self, jwkKeyListUrl, kid):
self.keyMap[hashKey] = self.get_key_uncached(jwkKeyListUrl, kid)
return self.keyMap[hashKey]

def get_key_uncached(self, jwkKeyListUrl, kid):
rest_client = rest.RESTClientObject()

def get_key_uncached(self, jwkKeyListUrl, kid):
version = self.package_version_provider.get_version()
headers = {
'User-Agent': f'Authress SDK; Python; {version};'
}
result = rest_client.get_request(jwkKeyListUrl, headers=headers)
result = self.http_client.request_with_retries('GET', jwkKeyListUrl, headers=headers)

for index, key in enumerate(json.loads(result.data)['keys']):
if key['kid'] == kid:
Expand Down
3 changes: 0 additions & 3 deletions authress/api/user_permissions_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
from authress.models.user_resources_collection import UserResourcesCollection
from authress.models.user_role_collection import UserRoleCollection

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -50,8 +49,6 @@ class UserPermissionsApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
3 changes: 0 additions & 3 deletions authress/api/users_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
from authress.models.user_identity import UserIdentity
from authress.models.user_identity_collection import UserIdentityCollection

from authress.http_client import HttpClient
from authress.api_response import ApiResponse
from authress.exceptions import ( # noqa: F401
ApiTypeError,
Expand All @@ -50,8 +49,6 @@ class UsersApi(object):
"""

def __init__(self, api_client=None):
if api_client is None:
api_client = HttpClient.get_default()
self.api_client = api_client

@validate_arguments
Expand Down
7 changes: 4 additions & 3 deletions authress/authress_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@
from authress.api import token_verifier

class AuthressClient(object):
def __init__(self, authress_api_url=None, service_client_access_key=None):
def __init__(self, authress_api_url=None, service_client_access_key=None, user_agent=None):
self._host = authress_api_url if authress_api_url.startswith('http') else f"https://{authress_api_url}"
self._host = re.sub(r'/+$', '', self._host)
self._token_verifier = token_verifier.TokenVerifier()
self._http_client = HttpClient(host=self._host, access_key=service_client_access_key)

self._http_client = HttpClient(host=self._host, access_key=service_client_access_key, user_agent=user_agent)
self._token_verifier = token_verifier.TokenVerifier(http_client=self._http_client)

def set_token(self, token: str):
self._http_client.set_token(token)
Expand Down
4 changes: 2 additions & 2 deletions authress/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class HttpClient(object):
}
_pool = None

def __init__(self, host=None, access_key=None):
def __init__(self, host=None, access_key=None, user_agent=None):
self.host = host if host is not None and host.startswith('http') else f"https://{host}"
self.access_key = access_key
self.pool_threads = 1
Expand All @@ -60,7 +60,7 @@ def __init__(self, host=None, access_key=None):
self.service_client_token_provider = service_client_token_provider.ServiceClientTokenProvider(self.access_key, self.host)

version = PackageVersionProvider().get_version()
self.default_headers['User-Agent'] = f'Authress SDK; Python; {version};'
self.default_headers['User-Agent'] = f'Authress SDK; Python; {version}; {user_agent or ""}'

def set_token(self, token):
self.default_headers['Authorization'] = f'Bearer {token.replace("Bearer", "").strip()}'
Expand Down
17 changes: 8 additions & 9 deletions test/test_service_client_token_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from authress.models import *
from authress.utils import ServiceClientTokenProvider, JwtManager
from authress import AuthressClient
from authress.http_client import HttpClient

import unittest
from unittest.mock import patch
Expand All @@ -27,10 +26,10 @@ def test_get_token(self):

access_key = 'eyJrZXlJZCI6ImNjYjFjZGJmLTM0NzYtNGNiNy05Njc1LTVlMzNmYjI5NTNjMyIsInByaXZhdGVLZXkiOiItLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS1cbk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRRFFidWFBd0V6VkJHZnZcbjBEL2JKSjRHa2JoV2oyRy9lYTF3UUZNeWxiK0ZzTDM1dGJvVHNIUGdvbUtGMDNNQkphWmRBVHhwcnhYa2xvYWNcblFhYkE4eXcyQ2lFbitHNjlMcUFnUVlLSmZzL1psWEo4MVJ0TkR0TkZRUTdPS0xpSGJrU1I1cFU3R0lKNENQZTZcbkxHM3UzUkVUbFFndmlhV2M2bzVOUkRMWTBIbzhya2w0Yk8rZjMycXg2SGV6dzBsUnZOK1I4L24vZUxLbCtGVlpcbk1yYzFkcmh5NDdtVU80ZnJKWW1LSzg2ZGZacVk4RVh2aGpjaFZzdHhSTXdtMlRDbUtWT2xsQWUrandmNTR5Q2NcbnUzcTNsRUxzcnhXTlRsVC9mRHBQQSt6MDh2MFdDa2ozdWo5SEh3REE1VjhZaUtJOEFheWRLSG9nYnA5eHp1amdcbnZwQmVacnRuQWdNQkFBRUNnZ0VBZnRpL0Z1UHcza0tNTG5vQ0lvK3FURDBxZmlOTVRZYnpjamp6YVBtUlVQODZcbjNsa21JUTFsdC9PYkdlNlJNc1dDOVY3bk1Ub0lqTkMrb3lHaEpoUFhlQnU2Q2VVN0g0N2NqRVRSK0hOZ2N2NXNcbmFtUVc5VkpzYU4wcThYUCt1UXoyVmdTS0ZTalpYY3UzVjJucWpVK2tNTktsNUtoVVRhYkJhMnh4dFZsS3l0bjlcbld6QnIzZExLVXBwYzdoZXFaa2diSHE2amZXd3h2Vk56cmhkNUZ1Tm5EeWI2R3QrUXhzYi83dmdhdnRsNmtXM0hcbnU5ZUtGcjJhdER4VHhaTDArRVIxWjVyV21MNzdUK3owQitYVkZJZ05ia2FlSURBZjEzRjBPSzE3YjJ4NmlSSjVcbnJCRTdCc0ZhMGVuOXBjSWN2UUxhbGFMREVOL1d2YWd4dnowSWZ4M1R3UUtCZ1FEbjVMSGhFczBzeWxYVUdrVlFcbmhFU1ZacGh5QzdFRHBZYm44UW5DNkI3ZDFtWkR1d1JuSkMyZXVxT1lNMFlVcWlGT3Q5RW9UMllNQy9jT2pUVTFcbndnMm9GQ0hqWUI4cGptNHVkb3B3MHRHcGRyb1piQVNkOHkzR1RuNitMK25tVGVzNjYxTGN6ekhSekhrTnh5OUJcbkNVNTRzWXhnK1M5bnhSTjdEVERxeTE2M1dRS0JnUURtR2Q1Snl4VnNyS3ZVSmFVbDM5ekZRcTh3cnpTZ0xZVVBcbjF0a1dHYWhIanFvRjYvSnM2YUZnZlYraXl5THk1dm03WEN0dUw2RGtEQW93NnVpS1NiRlhicnVCYW5GSDBnWktcbkRaVmVQcU9mbTVIYWJWalB1VmdPdW5HWHBOMnZ4QTdwNkg0SkMxOVkvUkg0MkY5bHE4aUtkejZXWHJYMjNPRHFcbjQrcHZtdzF3dndLQmdRQ0YyajlHNExobjR6OFptRFJzWG56TUZCVm90eER0UHUyWkVrd0ZJa0UyNFp2VCtxNTJcbjdxNGFramIrRXBLZ09QZlMzVTJ3eSt2bWhqMk1PN3Y4Rk5BWE5jKzkxRzBJYXJ0MHZGMzY4K1dyd09sNDVSM2hcbklrNUl5bVJrV1huVXd5TkZ0akgxWE8rdjN5djg1UDJFdDkrQTBWTnJZa3FYeG0wUk9UTUVSSEdldVFLQmdEZmdcbnNrMkRSc21rU1BuMHhsMGpOdTZrV2Z6ZG4wOENudHlRMVJqNzFCVEVmVitBdzlkVkNQNXdrOGZwd3F2d0VWZEJcbmM3NkhURy8weUlqR2t2LzZFMW5qSngrdlpLRUhUTVd3OU1QMVBERG5TNDBhbnNXYkFkcFp4bm9IN0ZuaHA2bC9cbjd4TnRNcE5lcVgyZnRkTHYyM3hjcHROSFhyTDdRcGRvRDZkWXBQUHJBb0dCQU5CN2QyME5kY1EzaTBmWGJ6dGhcbk1RUFIwK3NEVkViMUZjSUdXbDdPeXNvYy9UZ2prT3NhVDRTL2hXODg1RGR5ZnZHbjdpRmpyMDBPQVVyVjE5NlRcbmFwdDJNS0EvWVdWeG9Ud2kwZCs0UHZ5Mnk3SXBnMk9tcEE0bVliYnBXQ0NPS3dtczlEQ0E4MVVGeEJiMHdUbTdcbjlXVStVbGZMWDAvcGNkSFNEZkExbXVjZVxuLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLVxuIiwiYXVkaWVuY2UiOiIyMmJiYzUwMi0zYjdhLTRjNTQtOGE2ZS1jMDRhM2NhNGRmNWYuYWNjb3VudHMuYXV0aHJlc3MuaW8iLCJjbGllbnRJZCI6IjIzYjRiY2Q1LWMwYzEtNDYwMi05NGU1LThkYTgyNzNkMGRiMCJ9'

http_client = HttpClient("", access_key)
token1 = http_client._get_client_token()
service_client_token_provider = ServiceClientTokenProvider(access_key, "")
token1 = service_client_token_provider.get_client_token()
time.sleep(2)
token2 = http_client._get_client_token()
token2 = service_client_token_provider.get_client_token()
assert token1 == token2
pass

Expand All @@ -42,10 +41,10 @@ def test_get_token_for_eddsa(self):

access_key = 'CLIENT.KEY.ACCOUNT.MC4CAQAwBQYDK2VwBCIEIIM7npIckfT431rYzEeF+hCqvHogpOllmVSgINwqQv+g'

http_client = HttpClient("", access_key)
token1 = http_client._get_client_token()
service_client_token_provider = ServiceClientTokenProvider(access_key, "")
token1 = service_client_token_provider.get_client_token()
time.sleep(2)
token2 = http_client._get_client_token()
token2 = service_client_token_provider.get_client_token()
assert token1 == token2
pass

Expand All @@ -55,8 +54,8 @@ def test_get_token_without_access_key(self):
Ignores access keys that are None
"""

http_client = HttpClient("")
token1 = http_client._get_client_token()
service_client_token_provider = ServiceClientTokenProvider("")
token1 = service_client_token_provider.get_client_token()
assert token1 == None
pass

Expand Down
2 changes: 1 addition & 1 deletion test/test_token_verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_get_token_for_eddsa(self):
token_verifier_instance.get_key_uncached = mock_get_key_uncached
identity = token_verifier_instance.verify_token(authressCustomDomain=f"https://{customDomain}", token=access_key)

mock_get_key_uncached.assert_called_once_with(f"https://{customDomain}/v1/clients/CLIENT/.well-known/openid-configuration/jwks", "KEY")
mock_get_key_uncached.assert_called_once_with(f"https://{customDomain}/v1/clients/CLIENT/.well-known/openid-configuration/jwks?kid=KEY", "KEY")
assert identity['iss'] == f'https://{customDomain}/v1/clients/CLIENT'
assert identity['sub'] == "CLIENT"

Expand Down
Loading