diff --git a/src/aap_eda/api/serializers/event_stream.py b/src/aap_eda/api/serializers/event_stream.py index 9396edc26..910ca0798 100644 --- a/src/aap_eda/api/serializers/event_stream.py +++ b/src/aap_eda/api/serializers/event_stream.py @@ -12,12 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Optional +from urllib.parse import urljoin +import yaml +from django.conf import settings +from django.urls import reverse from rest_framework import serializers from aap_eda.api.serializers.eda_credential import EdaCredentialRefSerializer from aap_eda.api.serializers.organization import OrganizationRefSerializer -from aap_eda.core import models, validators +from aap_eda.core import enums, models, validators class EventStreamInSerializer(serializers.ModelSerializer): @@ -72,6 +76,7 @@ class EventStreamOutSerializer(serializers.ModelSerializer): eda_credential = EdaCredentialRefSerializer( required=True, allow_null=False ) + url = serializers.SerializerMethodField() class Meta: model = models.EventStream @@ -98,6 +103,16 @@ class Meta: *read_only_fields, ] + def get_url(self, obj) -> str: + path = reverse( + "external_event_stream-post", + kwargs={"pk": obj.uuid}, + ).lstrip("/") + inputs = yaml.safe_load(obj.eda_credential.inputs.get_secret_value()) + if inputs.get("auth_type", None) == enums.EventStreamAuthType.MTLS: + return urljoin(settings.EVENT_STREAM_MTLS_BASE_URL, path) + return urljoin(settings.EVENT_STREAM_BASE_URL, path) + def get_owner(self, obj) -> str: return f"{obj.owner.username}" diff --git a/src/aap_eda/api/views/event_stream.py b/src/aap_eda/api/views/event_stream.py index 421271cad..993f6488b 100644 --- a/src/aap_eda/api/views/event_stream.py +++ b/src/aap_eda/api/views/event_stream.py @@ -13,12 +13,9 @@ # limitations under the License. """EventStream configuration API Set.""" import logging -from urllib.parse import urljoin -import yaml from ansible_base.rbac.api.related import check_related_permissions from ansible_base.rbac.models import RoleDefinition -from django.conf import settings from django.db import transaction from django.forms import model_to_dict from django_filters import rest_framework as defaultfilters @@ -33,13 +30,11 @@ from aap_eda.api import exceptions as api_exc, filters, serializers from aap_eda.core import models -from aap_eda.core.enums import EventStreamAuthType, ResourceType +from aap_eda.core.enums import ResourceType from aap_eda.core.utils import logging_utils logger = logging.getLogger(__name__) -EVENT_STREAM_EXTERNAL_PATH = "api/eda/v1/external_event_stream" - resource_name = "EventStream" @@ -187,19 +182,6 @@ def create(self, request, *args, **kwargs): RoleDefinition.objects.give_creator_permissions( request.user, serializer.instance ) - inputs = yaml.safe_load( - response.eda_credential.inputs.get_secret_value() - ) - sub_path = f"{EVENT_STREAM_EXTERNAL_PATH}/{response.uuid}/post/" - if inputs["auth_type"] == EventStreamAuthType.MTLS: - response.url = urljoin( - settings.EVENT_STREAM_MTLS_BASE_URL, sub_path - ) - else: - response.url = urljoin( - settings.EVENT_STREAM_BASE_URL, sub_path - ) - response.save(update_fields=["url"]) logger.info( logging_utils.generate_simple_audit_log( diff --git a/src/aap_eda/core/migrations/0052_remove_eventstream_url.py b/src/aap_eda/core/migrations/0052_remove_eventstream_url.py new file mode 100644 index 000000000..aaeec1e9d --- /dev/null +++ b/src/aap_eda/core/migrations/0052_remove_eventstream_url.py @@ -0,0 +1,16 @@ +# Generated by Django 4.2.7 on 2024-10-22 20:50 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("core", "0051_alter_activation_organization_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="eventstream", + name="url", + ), + ] diff --git a/src/aap_eda/core/models/event_stream.py b/src/aap_eda/core/models/event_stream.py index aaebeff3a..3943d67e8 100644 --- a/src/aap_eda/core/models/event_stream.py +++ b/src/aap_eda/core/models/event_stream.py @@ -29,7 +29,6 @@ class EventStream(BaseOrgModel, UniqueNamedModel): help_text="The type of the event stream based on credential type", default="hmac", ) - eda_credential = models.ForeignKey( "EdaCredential", blank=True, @@ -45,11 +44,9 @@ class EventStream(BaseOrgModel, UniqueNamedModel): "are comma delimited" ), ) - test_mode = models.BooleanField( default=False, help_text="Enable test mode" ) - test_content_type = models.TextField( blank=True, default="", @@ -76,7 +73,6 @@ class EventStream(BaseOrgModel, UniqueNamedModel): default="", help_text="The error message, when in test mode", ) - owner = models.ForeignKey( "User", on_delete=models.CASCADE, @@ -84,10 +80,6 @@ class EventStream(BaseOrgModel, UniqueNamedModel): help_text="The user who created the webhook", ) uuid = models.UUIDField(default=uuid.uuid4) - url = models.TextField( - null=False, - help_text="The URL which will be used to post to the event stream", - ) created_at = models.DateTimeField(auto_now_add=True, null=False) modified_at = models.DateTimeField(auto_now=True, null=False) events_received = models.BigIntegerField( diff --git a/tests/integration/api/test_activation_with_event_stream.py b/tests/integration/api/test_activation_with_event_stream.py index 59ac73f9a..f76bb9b68 100644 --- a/tests/integration/api/test_activation_with_event_stream.py +++ b/tests/integration/api/test_activation_with_event_stream.py @@ -222,6 +222,26 @@ def create_activation_related_data( else None ) + hmac_credential_type = models.CredentialType.objects.get( + name=enums.EventStreamCredentialType.HMAC + ) + hmac_credential_id = models.EdaCredential.objects.create( + name="default-hmac-credential", + description="Default HMAC Credential", + credential_type=hmac_credential_type, + inputs=inputs_to_store( + { + "auth_type": "hmac", + "hmac_algorithm": "sha256", + "secret": "secret", + "header_key": "X-Hub-Signature-256", + "hmac_format": "hex", + "hmac_signature_prefix": "sha256=", + } + ), + organization=organization, + ).id + event_streams = [] for name in event_stream_names: event_stream = models.EventStream.objects.create( @@ -229,6 +249,7 @@ def create_activation_related_data( name=name, owner=user, organization=organization, + eda_credential_id=hmac_credential_id, ) event_streams.append(event_stream) diff --git a/tests/integration/api/test_event_stream.py b/tests/integration/api/test_event_stream.py index 78b36a289..67ac978c8 100644 --- a/tests/integration/api/test_event_stream.py +++ b/tests/integration/api/test_event_stream.py @@ -75,14 +75,33 @@ def test_retrieve_event_stream( default_vault_credential, ): event_stream = default_event_streams[0] - response = admin_client.get( - f"{api_url_v1}/event-streams/{event_stream.id}/" - ) + with override_settings( + EVENT_STREAM_BASE_URL="https://www.example.com/ohlala/", + ): + response = admin_client.get( + f"{api_url_v1}/event-streams/{event_stream.id}/" + ) + assert response.status_code == status.HTTP_200_OK assert response.data["name"] == default_event_streams[0].name - assert response.data["url"] == default_event_streams[0].url assert response.data["owner"] == "luke.skywalker" + uuid = default_event_streams[0].uuid + base_url = f"https://www.example.com/ohlala{api_url_v1}" + expected_url = f"{base_url}/external_event_stream/{uuid}/post/" + assert response.data["url"] == expected_url + + # Verify the url is dynamic + with override_settings( + EVENT_STREAM_BASE_URL="https://www.example2.com/ohlala2/", + ): + response = admin_client.get( + f"{api_url_v1}/event-streams/{event_stream.id}/" + ) + assert response.data["url"].startswith( + "https://www.example2.com/ohlala2/" + ) + @pytest.mark.django_db def test_create_event_stream( diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index e16aa81b2..3ed2ad433 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -36,7 +36,6 @@ from aap_eda.services.activation.engine.common import ContainerEngine DUMMY_UUID = "8472ff2c-6045-4418-8d4e-46f6cffc8557" -DUMMY_URL = "https://www.example.com" ################################################################# @@ -1187,7 +1186,6 @@ def default_event_streams( name="test-es-1", owner=default_user, organization=default_organization, - url=DUMMY_URL, eda_credential=default_hmac_credential, test_mode=False, ), @@ -1196,7 +1194,6 @@ def default_event_streams( name="another-test-es-2", owner=default_user, organization=default_organization, - url=DUMMY_URL, eda_credential=default_hmac_credential, test_mode=True, ), @@ -1215,7 +1212,6 @@ def default_event_stream( name="test-es-1", owner=default_user, organization=default_organization, - url=DUMMY_URL, eda_credential=default_hmac_credential, )