Skip to content

Commit

Permalink
transient identifier based on traits, enforce transient traits for al…
Browse files Browse the repository at this point in the history
…l identities
  • Loading branch information
khvn26 committed Aug 8, 2024
1 parent 5437e8e commit ada1826
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
27 changes: 22 additions & 5 deletions api/environments/sdk/services.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import uuid
import hashlib
from itertools import chain
from operator import itemgetter
from typing import TypeAlias

from django.utils import timezone
Expand All @@ -18,15 +19,16 @@ def get_transient_identity_and_traits(
) -> IdentityAndTraits:
"""
Get a transient `Identity` instance with a randomly generated identifier.
All traits are marked as transient.
"""
return (
(
identity := _get_transient_identity(
environment=environment,
identifier=str(uuid.uuid4()),
identifier=get_transient_identifier(sdk_trait_data),
)
),
identity.generate_traits(sdk_trait_data, persist=False),
identity.generate_traits(_ensure_transient(sdk_trait_data), persist=False),
)


Expand All @@ -41,8 +43,7 @@ def get_identified_transient_identity_and_traits(
combined with incoming traits provided to `sdk_trait_data` argument.
All traits constructed from `sdk_trait_data` are marked as transient.
"""
for sdk_trait_data_item in sdk_trait_data:
sdk_trait_data_item["transient"] = True
sdk_trait_data = _ensure_transient(sdk_trait_data)
if identity := Identity.objects.filter(
environment=environment,
identifier=identifier,
Expand Down Expand Up @@ -89,6 +90,16 @@ def get_persisted_identity_and_traits(
)


def get_transient_identifier(sdk_trait_data: list[SDKTraitData]) -> str:
return hashlib.sha256(
"".join(
f'{trait["trait_key"]}{trait["trait_value"]}'
for trait in sorted(sdk_trait_data, key=itemgetter("trait_key"))
).encode(),
usedforsecurity=False,
).hexdigest()


def _get_transient_identity(
environment: Environment,
identifier: str,
Expand All @@ -98,3 +109,9 @@ def _get_transient_identity(
environment=environment,
identifier=identifier,
)


def _ensure_transient(sdk_trait_data: list[SDKTraitData]) -> list[SDKTraitData]:
for sdk_trait_data_item in sdk_trait_data:
sdk_trait_data_item["transient"] = True
return sdk_trait_data
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import hashlib
import json
from typing import Any, Generator
from unittest import mock

import pytest
from django.urls import reverse
from pytest_lazyfixture import lazy_fixture
from pytest_mock import MockerFixture
from rest_framework import status
from rest_framework.test import APIClient

Expand Down Expand Up @@ -236,12 +236,13 @@ def existing_identity_identifier_data(


@pytest.fixture
def transient_random_identifier(
mocker: MockerFixture,
def transient_identifier(
segment_condition_property: str,
segment_condition_value: str,
) -> Generator[str, None, None]:
uuid_mock = mocker.patch("environments.sdk.services.uuid", autospec=True)
uuid_mock.uuid4.return_value = identifier = "1199c22c-4dcb-4505-9857-5db5f258469c"
yield identifier
return hashlib.sha256(
f"avalue_a{segment_condition_property}{segment_condition_value}".encode()
).hexdigest()


@pytest.mark.parametrize(
Expand All @@ -263,17 +264,15 @@ def transient_random_identifier(
pytest.param({"identifier": "unseen"}, "unseen", id="new-identifier"),
pytest.param(
{"identifier": ""},
lazy_fixture("transient_random_identifier"),
lazy_fixture("transient_identifier"),
id="blank-identifier",
),
pytest.param(
{"identifier": None},
lazy_fixture("transient_random_identifier"),
lazy_fixture("transient_identifier"),
id="null-identifier",
),
pytest.param(
{}, lazy_fixture("transient_random_identifier"), id="missing-identifier"
),
pytest.param({}, lazy_fixture("transient_identifier"), id="missing-identifier"),
],
)
def test_get_feature_states_for_identity__segment_match_expected(
Expand Down Expand Up @@ -303,7 +302,8 @@ def test_get_feature_states_for_identity__segment_match_expected(
{
"trait_key": segment_condition_property,
"trait_value": segment_condition_value,
}
},
{"trait_key": "a", "trait_value": "value_a"},
],
}
),
Expand Down

0 comments on commit ada1826

Please sign in to comment.