diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 876970a..37c78ca 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,6 +1,8 @@ import os import secrets import time +import string +import random from distutils.util import strtobool import pytest @@ -11,7 +13,8 @@ from threescale_api.resources import (Service, ApplicationPlan, Application, Proxy, Backend, Metric, MappingRule, BackendMappingRule, BackendUsage, - ActiveDoc, Webhooks, InvoiceState) + ActiveDoc, Webhooks, InvoiceState, + ApplicationKey) load_dotenv() @@ -140,6 +143,19 @@ def application(account, application_plan, application_params) -> Application: cleanup(resource) +@pytest.fixture(scope='module') +def app_key_params(account, application): + value = ''.join(random.choices(string.ascii_uppercase + string.digits + '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', k=100)) + return({"application_id": application["id"], "account_id": account["id"], "key": value}) + + +@pytest.fixture(scope='module') +def app_key(application, app_key_params) -> ApplicationKey: + resource = application.keys.create(params=app_key_params) + yield resource + cleanup(resource) + + @pytest.fixture(scope='module') def proxy(service, application, api_backend) -> Proxy: params = { diff --git a/tests/integration/test_integration_application.py b/tests/integration/test_integration_application.py index 2195131..24102c3 100644 --- a/tests/integration/test_integration_application.py +++ b/tests/integration/test_integration_application.py @@ -25,3 +25,13 @@ def test_application_update(application, update_application_params): updated_application = application.update(params=update_application_params) asserts.assert_resource(updated_application) asserts.assert_resource_params(updated_application, update_application_params) + + +def test_application_key_can_be_created(app_key, app_key_params): + asserts.assert_resource(app_key) + asserts.assert_resource_params(app_key, app_key_params) + + +def test_application_key_list(application, app_key): + keys = application.keys.list() + assert len(keys) > 0 diff --git a/threescale_api/auth.py b/threescale_api/auth.py index 39d62ce..86425d3 100644 --- a/threescale_api/auth.py +++ b/threescale_api/auth.py @@ -57,7 +57,7 @@ def __init__(self, app, location=None): proxy = self.app.service.proxy.list() self.credentials = { proxy["auth_app_id"]: self.app["application_id"], - proxy["auth_app_key"]: self.app.keys.list()["keys"][0]["key"]["value"] + proxy["auth_app_key"]: self.app.keys.list()[-1]["value"] } def __call__(self, request): diff --git a/threescale_api/resources.py b/threescale_api/resources.py index 9c1838c..8f19e8d 100644 --- a/threescale_api/resources.py +++ b/threescale_api/resources.py @@ -1,6 +1,7 @@ import logging from enum import Enum from typing import Dict, Union, List, Iterable +from urllib.parse import quote_plus from threescale_api import auth from threescale_api import utils @@ -316,7 +317,7 @@ def url(self) -> str: class ApplicationKeys(DefaultClient): - def __init__(self, *args, entity_name='application', entity_collection='applications', + def __init__(self, *args, entity_name='key', entity_collection='keys', **kwargs): super().__init__(*args, entity_name=entity_name, entity_collection=entity_collection, **kwargs) @@ -325,6 +326,30 @@ def __init__(self, *args, entity_name='application', entity_collection='applicat def url(self) -> str: return self.parent.url + '/keys' + def create(self, params: dict = None, **kwargs) -> 'ApplicationKey': + """Create a new instance of ApplicationKey. "keys" POST request + returns Application instead of newly create key. + Returns: Newly created key. + + """ + super().create(params=params, **kwargs) + key = sorted(self.list(), key=lambda key: key["created_at"])[-1] + key.entity_id = quote_plus(key["value"]) + return key + + def list(self, **kwargs) -> List['ApplicationKey']: + """List all entities of ApplicationKey. + There is no id in list response, so it needs to be assigned the value + to be able to work with key instance. + Args: + **kwargs: Optional parameters + Returns(List['ApplicationKey']): List of ApplicationKey resources + """ + key_list = super().list(**kwargs) + for key in key_list: + key.entity_id = quote_plus(key["value"]) + return key_list + class Providers(DefaultClient): def __init__(self, *args, entity_name='user', entity_collection='users', **kwargs): @@ -1320,7 +1345,7 @@ def service(self) -> 'Service': @property def keys(self): "Application keys" - return ApplicationKeys(parent=self, instance_klass=DefaultResource) + return ApplicationKeys(parent=self, instance_klass=ApplicationKey) def authobj(self, auth_mode=None, location=None): """Returns subclass of requests.auth.BaseAuth to provide authentication @@ -1396,6 +1421,11 @@ def test_request(self, relpath=None, verify: bool = None): return client.get(relpath) +class ApplicationKey(DefaultResource): + def __init__(self, entity_name='', **kwargs): + super().__init__(entity_name=entity_name, **kwargs) + + class Account(DefaultResource): def __init__(self, entity_name='org_name', **kwargs): super().__init__(entity_name=entity_name, **kwargs)