This is an automated email from the ASF dual-hosted git repository. jsinovassinnaik pushed a commit to branch UNOMI-822 in repository https://gitbox.apache.org/repos/asf/unomi.git
commit 53ab858c7e2a0e0b06edb3f81e560dd7c1f4de67 Author: David Griffon <dgrif...@jahia.com> AuthorDate: Wed Apr 17 09:05:36 2024 +0200 UNOMI-825: add concealed profile properties (#656) --- .../META-INF/cxs/schemas/events/search/search.json | 33 +++++++++++++++ .../schemas/events/search/search.properties.json | 28 +++++++++++++ .../org/apache/unomi/itests/ContextServletIT.java | 48 ++++++++++++++++++++++ .../unomi/rest/endpoints/ContextJsonEndpoint.java | 17 ++++---- 4 files changed, 119 insertions(+), 7 deletions(-) diff --git a/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/search/search.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/search/search.json new file mode 100644 index 000000000..ab8ee1233 --- /dev/null +++ b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/search/search.json @@ -0,0 +1,33 @@ +{ + "$id": "https://unomi.apache.org/schemas/json/events/search/1-0-0", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "self": { + "vendor": "org.apache.unomi", + "target": "events", + "name": "search", + "format": "jsonschema", + "version": "1-0-0" + }, + "title": "SearchEvent", + "type": "object", + "allOf": [ + { + "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0" + } + ], + "properties": { + "properties": { + "$ref": "https://unomi.apache.org/schemas/json/events/search/properties/1-0-0" + }, + "source": { + "$ref": "https://unomi.apache.org/schemas/json/items/page/1-0-0" + }, + "target": { + "$ref": "https://unomi.apache.org/schemas/json/item/1-0-0" + }, + "flattenedProperties": { + "$ref": "https://unomi.apache.org/schemas/json/events/form/flattenedProperties/1-0-0" + } + }, + "unevaluatedProperties": false +} diff --git a/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/search/search.properties.json b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/search/search.properties.json new file mode 100644 index 000000000..58c9d3677 --- /dev/null +++ b/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/search/search.properties.json @@ -0,0 +1,28 @@ +{ + "$id": "https://unomi.apache.org/schemas/json/events/search/properties/1-0-0", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "self": { + "vendor": "org.apache.unomi", + "name": "searchProperties", + "format": "jsonschema", + "version": "1-0-0" + }, + "title": "searchProperties", + "type": "object", + "properties": { + "originForm": { + "type": "string" + }, + "language": { + "type": "string", + "maxLength": 5 + }, + "keyword": { + "type": "string" + }, + "origin": { + "type": "string" + } + }, + "unevaluatedProperties": false +} diff --git a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java index 10ed9e137..dfaaa6641 100644 --- a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java @@ -854,6 +854,54 @@ public class ContextServletIT extends BaseIT { DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); } + @Test + public void testConcealedProperties() throws Exception { + String sessionId = "test-concealed-property-session-id"; + // Add custom profile property type + PropertyType customPropertyType = new PropertyType(new Metadata("customProperty")); + customPropertyType.setValueTypeId("text"); + profileService.setPropertyType(customPropertyType); + // New profile with the custom property type + Profile profile = new Profile("test-profile-id" + System.currentTimeMillis()); + profile.setProperty("customProperty", "concealedValue"); + profileService.save(profile); + + Thread.sleep(2000); + // Get it from all properties + ContextRequest contextRequest = new ContextRequest(); + contextRequest.setRequiredProfileProperties(Arrays.asList("*")); + contextRequest.setProfileId(profile.getItemId()); + contextRequest.setSessionId(sessionId); + HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL)); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.APPLICATION_JSON)); + assertEquals(TestUtils.executeContextJSONRequest(request, sessionId).getContextResponse().getProfileProperties().get("customProperty"), ("concealedValue")); + // set the property as concealed + customPropertyType.getMetadata().getSystemTags().add("concealed"); + profileService.deletePropertyType(customPropertyType.getItemId()); + profileService.setPropertyType(customPropertyType); + // Not in all properties + request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.APPLICATION_JSON)); + assertNull(TestUtils.executeContextJSONRequest(request, sessionId).getContextResponse().getProfileProperties().get("customProperty")); + // Got it explicitly + contextRequest.setRequiredProfileProperties(Arrays.asList("customProperty")); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.APPLICATION_JSON)); + assertEquals(TestUtils.executeContextJSONRequest(request, sessionId).getContextResponse().getProfileProperties().get("customProperty"), ("concealedValue")); + // Got it with all + contextRequest.setRequiredProfileProperties(Arrays.asList("*", "customProperty")); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.APPLICATION_JSON)); + assertEquals(TestUtils.executeContextJSONRequest(request, sessionId).getContextResponse().getProfileProperties().get("customProperty"), ("concealedValue")); + + // remove the concealed tag on the property type + customPropertyType.getMetadata().getSystemTags().remove("concealed"); + profileService.deletePropertyType(customPropertyType.getItemId()); + profileService.setPropertyType(customPropertyType); + + // Got it from all properties + contextRequest.setRequiredProfileProperties(Arrays.asList("*")); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.APPLICATION_JSON)); + assertEquals(TestUtils.executeContextJSONRequest(request, sessionId).getContextResponse().getProfileProperties().get("customProperty"), ("concealedValue")); + } + private Boolean getPersistedControlGroupStatus(SystemPropertiesItem systemPropertiesItem, String personalizationId) { if(systemPropertiesItem.getSystemProperties() != null && systemPropertiesItem.getSystemProperties().containsKey("personalizationStrategyStatus")) { List<Map<String, Object>> personalizationStrategyStatus = (List<Map<String, Object>>) systemPropertiesItem.getSystemProperties().get("personalizationStrategyStatus"); diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java index 407eb5f87..df04e6d6c 100644 --- a/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java +++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java @@ -42,13 +42,8 @@ import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; @WebService @Consumes(MediaType.APPLICATION_JSON) @@ -78,6 +73,8 @@ public class ContextJsonEndpoint { private RestServiceUtils restServiceUtils; @Reference private SchemaService schemaService; + @Reference + private ProfileService profileService; @OPTIONS @Path("/context.js") @@ -224,6 +221,12 @@ public class ContextJsonEndpoint { Map<String, Object> profileProperties = new HashMap<>(eventsRequestContext.getProfile().getProperties()); if (!contextRequest.getRequiredProfileProperties().contains("*")) { profileProperties.keySet().retainAll(contextRequest.getRequiredProfileProperties()); + } else { + // get public properties + explicit properties + Set<String> concealedProperties = profileService.getPropertyTypeBySystemTag("concealed").stream().map(Item::getItemId).collect(Collectors.toSet()); + // remove requested properties from the filtered properties + concealedProperties.removeAll(contextRequest.getRequiredProfileProperties().stream().filter(p -> !p.equals("*")).collect(Collectors.toList())); + profileProperties.keySet().removeAll(concealedProperties); } data.setProfileProperties(profileProperties); }