This is an automated email from the ASF dual-hosted git repository.

dgriffon pushed a commit to branch UNOMI-825-add-concealed-profile-properties
in repository https://gitbox.apache.org/repos/asf/unomi.git

commit 73908fa5943891063471320573017cae5e65dc1f
Author: david.griffon <dgrif...@jahia.com>
AuthorDate: Tue Apr 16 07:56:19 2024 +0200

    UNOMI-825: add concealed profile properties
---
 itests/README.md                                   |   2 +-
 .../org/apache/unomi/itests/ContextServletIT.java  | 691 +--------------------
 .../unomi/rest/endpoints/ContextJsonEndpoint.java  |  17 +-
 3 files changed, 44 insertions(+), 666 deletions(-)

diff --git a/itests/README.md b/itests/README.md
index 7be12dcd0..7da3a0e24 100644
--- a/itests/README.md
+++ b/itests/README.md
@@ -83,7 +83,7 @@ 
https://maven.apache.org/surefire/maven-failsafe-plugin/examples/single-test.htm
 Here's an example:
 
     mvn clean install -Dit.karaf.debug=hold:true 
-Dit.test=org.apache.unomi.itests.graphql.GraphQLEventIT
-
+mvn clean install -Dit.karaf.debug=hold:true,port=5006 
-Dit.test=org.apache.unomi.itests.ContextServletIT
 ## Migration tests
 
 Migration can now be tested, by reusing an ElasticSearch snapshot. 
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..d513a296e 100644
--- a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
@@ -139,676 +139,51 @@ public class ContextServletIT extends BaseIT {
     }
 
     @Test
-    public void testUpdateEventFromContextAuthorizedThirdParty_Success() 
throws Exception {
-        //Arrange
-        String eventId = "test-event-id-" + System.currentTimeMillis();
-        String sessionId = "test-session-id";
-        String scope = TEST_SCOPE;
-        String eventTypeOriginal = "test-event-type-original";
-        Profile profile = new Profile(TEST_PROFILE_ID);
-        Session session = new Session(sessionId, profile, new Date(), scope);
-        Event event = new Event(eventId, eventTypeOriginal, session, profile, 
scope, null, null, new Date());
+    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);
 
-        keepTrying("Profile " + TEST_PROFILE_ID + " not found in the required 
time", () -> profileService.load(TEST_PROFILE_ID),
-                Objects::nonNull, DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-
-        this.eventService.send(event);
-
-        keepTrying("Event " + eventId + " not updated in the required time", 
() -> this.eventService.getEvent(eventId),
-                savedEvent -> Objects.nonNull(savedEvent) && 
eventTypeOriginal.equals(savedEvent.getEventType()), DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-
-        event.setEventType(TEST_EVENT_TYPE); //change the event so we can see 
the update effect
-
-        //Act
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setSessionId(session.getItemId());
-        contextRequest.setEvents(Arrays.asList(event));
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.addHeader(THIRD_PARTY_HEADER_NAME, UNOMI_KEY);
-        request.setEntity(new 
StringEntity(objectMapper.writeValueAsString(contextRequest), 
ContentType.APPLICATION_JSON));
-        TestUtils.executeContextJSONRequest(request, sessionId);
-
-        event = keepTrying("Event " + eventId + " not updated in the required 
time", () -> eventService.getEvent(eventId),
-                savedEvent -> Objects.nonNull(savedEvent) && 
TEST_EVENT_TYPE.equals(savedEvent.getEventType()), DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-        assertEquals(2, event.getVersion().longValue());
-    }
-
-    @Test
-    public void testCallingContextWithSessionCreation() throws Exception {
-        //Arrange
-        String eventId = "test-event-id-" + System.currentTimeMillis();
-        String sessionId = "test-session-id";
-        Profile profile = new Profile(TEST_PROFILE_ID);
-        profileService.save(profile);
-
-        keepTrying("Profile " + TEST_PROFILE_ID + " not found in the required 
time", () -> profileService.load(TEST_PROFILE_ID),
-                Objects::nonNull, DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-
-        //Act
-        Event event = new Event(TEST_EVENT_TYPE, null, profile, TEST_SCOPE, 
null, null, new Date());
-
+        Thread.sleep(2000);
+        // Get it from all properties
         ContextRequest contextRequest = new ContextRequest();
+        contextRequest.setRequiredProfileProperties(Arrays.asList("*"));
+        contextRequest.setProfileId(profile.getItemId());
         contextRequest.setSessionId(sessionId);
-        contextRequest.setEvents(Collections.singletonList(event));
         HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.addHeader(THIRD_PARTY_HEADER_NAME, UNOMI_KEY);
         request.setEntity(new 
StringEntity(objectMapper.writeValueAsString(contextRequest), 
ContentType.APPLICATION_JSON));
-        TestUtils.executeContextJSONRequest(request, sessionId);
-
-        Session session = keepTrying("Session with the id " + sessionId + " 
not saved in the required time",
-                () -> profileService.loadSession(sessionId), Objects::nonNull, 
DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-
-        assertEquals(TEST_EVENT_TYPE, session.getOriginEventTypes().get(0));
-        assertFalse(session.getOriginEventIds().isEmpty());
-    }
-
-    @Test
-    public void testUpdateEventFromContextUnAuthorizedThirdParty_Fail() throws 
Exception {
-        //Arrange
-        String eventId = "test-event-id-" + System.currentTimeMillis();
-        String sessionId = "test-session-id";
-        String scope = TEST_SCOPE;
-        String eventTypeOriginal = "test-event-type-original";
-        String eventTypeUpdated = TEST_EVENT_TYPE;
-        Profile profile = new Profile(TEST_PROFILE_ID);
-        Session session = new Session(sessionId, profile, new Date(), scope);
-        Event event = new Event(eventId, eventTypeOriginal, session, profile, 
scope, null, null, new Date());
-        profileService.save(profile);
-
-        keepTrying("Profile " + TEST_PROFILE_ID + " not found in the required 
time", () -> profileService.load(TEST_PROFILE_ID),
-                Objects::nonNull, DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-
-        this.eventService.send(event);
-
-        keepTrying("Event " + eventId + " not saved in the required time", () 
-> this.eventService.getEvent(eventId),
-                savedEvent -> Objects.nonNull(savedEvent) && 
eventTypeOriginal.equals(savedEvent.getEventType()), DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-
-        event.setEventType(eventTypeUpdated); //change the event so we can see 
the update effect
-
-        //Act
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setSessionId(session.getItemId());
-        contextRequest.setEvents(Arrays.asList(event));
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
+        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));
-        TestUtils.executeContextJSONRequest(request, sessionId);
-
-        // Check event type did not changed
-        event = shouldBeTrueUntilEnd("Event type should not have changed", () 
-> eventService.getEvent(eventId),
-                (savedEvent) -> 
eventTypeOriginal.equals(savedEvent.getEventType()), DEFAULT_TRYING_TIMEOUT, 
10);
-        assertEquals(1, event.getVersion().longValue());
-    }
-
-    @Test
-    public void testUpdateEventFromContextAuthorizedThirdPartyNoItemID_Fail() 
throws Exception {
-        //Arrange
-        String eventId = "test-event-id-" + System.currentTimeMillis();
-        String sessionId = "test-session-id";
-        String scope = TEST_SCOPE;
-        String eventTypeOriginal = "test-event-type-original";
-        String eventTypeUpdated = TEST_EVENT_TYPE;
-        Session session = new Session(sessionId, profile, new Date(), scope);
-        Event event = new Event(eventId, eventTypeOriginal, session, profile, 
scope, null, null, new Date());
-        this.eventService.send(event);
-
-        keepTrying("Event " + eventId + " not saved in the required time", () 
-> this.eventService.getEvent(eventId),
-                savedEvent -> Objects.nonNull(savedEvent) && 
eventTypeOriginal.equals(savedEvent.getEventType()), DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-
-        event.setEventType(eventTypeUpdated); //change the event so we can see 
the update effect
-
-        //Act
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setSessionId(session.getItemId());
-        contextRequest.setEvents(Arrays.asList(event));
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
+        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));
-        TestUtils.executeContextJSONRequest(request, sessionId);
-
-        // Check event type did not changed
-        event = shouldBeTrueUntilEnd("Event type should not have changed", () 
-> eventService.getEvent(eventId),
-                (savedEvent) -> 
eventTypeOriginal.equals(savedEvent.getEventType()), DEFAULT_TRYING_TIMEOUT, 
10);
-
-        assertEquals(1, event.getVersion().longValue());
-    }
-
-    @Test
-    public void testCreateEventsWithNoTimestampParam_profileAddedToSegment() 
throws Exception {
-        //Arrange
-        String sessionId = "test-session-id";
-        String scope = TEST_SCOPE;
-        Event event = new Event();
-        event.setEventType(TEST_EVENT_TYPE);
-        event.setScope(scope);
-
-        //Act
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setSessionId(sessionId);
-        contextRequest.setRequireSegments(true);
-        contextRequest.setEvents(Arrays.asList(event));
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(new 
StringEntity(objectMapper.writeValueAsString(contextRequest), 
ContentType.APPLICATION_JSON));
-        String cookieHeaderValue = 
TestUtils.executeContextJSONRequest(request, sessionId).getCookieHeaderValue();
-
-        refreshPersistence(Event.class);
-
-        //Add the context-profile-id cookie to the second event
-        request.addHeader("Cookie", cookieHeaderValue);
-        ContextResponse response = 
(TestUtils.executeContextJSONRequest(request, sessionId)).getContextResponse(); 
//second event
-
-        //Assert
-        assertEquals(1, response.getProfileSegments().size());
-        assertThat(response.getProfileSegments(), hasItem(SEGMENT_ID));
-
-    }
-
-    @Test
-    public void 
testCreateEventWithTimestampParam_pastEvent_profileIsNotAddedToSegment() throws 
Exception {
-        //Arrange
-        String sessionId = "test-session-id";
-        String scope = TEST_SCOPE;
-        Event event = new Event();
-        event.setEventType(TEST_EVENT_TYPE);
-        event.setScope(scope);
-        String regularURI = getFullUrl(CONTEXT_URL);
-        long oldTimestamp = 
LocalDateTime.now(ZoneId.of("UTC")).minusDays(SEGMENT_NUMBER_OF_DAYS + 
1).toInstant(ZoneOffset.UTC)
-                .toEpochMilli();
-        String customTimestampURI = regularURI + "?timestamp=" + oldTimestamp;
-
-        //Act
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setSessionId(sessionId);
-        contextRequest.setRequireSegments(true);
-        contextRequest.setEvents(Arrays.asList(event));
-        HttpPost request = new HttpPost(regularURI);
-        request.setEntity(new 
StringEntity(objectMapper.writeValueAsString(contextRequest), 
ContentType.APPLICATION_JSON));
-        //The first event is with a default timestamp (now)
-        String cookieHeaderValue = 
TestUtils.executeContextJSONRequest(request, sessionId).getCookieHeaderValue();
-        //The second event is with a customized timestamp
-        request.setURI(URI.create(customTimestampURI));
-        request.addHeader("Cookie", cookieHeaderValue);
-        ContextResponse response = 
(TestUtils.executeContextJSONRequest(request, sessionId)).getContextResponse(); 
//second event
-
-        shouldBeTrueUntilEnd("Profile " + response.getProfileId() + " not 
found in the required time",
-                () -> profileService.load(response.getProfileId()),
-                (savedProfile) -> Objects.nonNull(savedProfile) && 
!savedProfile.getSegments().contains(SEGMENT_ID), DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-    }
-
-    @Test
-    public void 
testCreateEventWithTimestampParam_futureEvent_profileIsNotAddedToSegment() 
throws Exception {
-        //Arrange
-        String sessionId = "test-session-id";
-        String scope = TEST_SCOPE;
-        Event event = new Event();
-        event.setEventType(TEST_EVENT_TYPE);
-        event.setScope(scope);
-        String regularURI = getFullUrl(CONTEXT_URL);
-        long futureTimestamp = 
LocalDateTime.now(ZoneId.of("UTC")).plusDays(1).toInstant(ZoneOffset.UTC).toEpochMilli();
-        String customTimestampURI = regularURI + "?timestamp=" + 
futureTimestamp;
-
-        //Act
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setSessionId(sessionId);
-        contextRequest.setRequireSegments(true);
-        contextRequest.setEvents(Arrays.asList(event));
-        HttpPost request = new HttpPost(regularURI);
-        request.setEntity(new 
StringEntity(objectMapper.writeValueAsString(contextRequest), 
ContentType.APPLICATION_JSON));
-        //The first event is with a default timestamp (now)
-        String cookieHeaderValue = 
TestUtils.executeContextJSONRequest(request, sessionId).getCookieHeaderValue();
-
-        //The second event is with a customized timestamp
-        request.setURI(URI.create(customTimestampURI));
-        request.addHeader("Cookie", cookieHeaderValue);
-        ContextResponse response = 
TestUtils.executeContextJSONRequest(request, sessionId).getContextResponse(); 
//second event
-
-        shouldBeTrueUntilEnd("Profile " + response.getProfileId() + " not 
found in the required time",
-                () -> profileService.load(response.getProfileId()),
-                (savedProfile) -> Objects.nonNull(savedProfile) && 
!savedProfile.getSegments().contains(SEGMENT_ID), DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-    }
-
-    @Test
-    public void testCreateEventWithProfileId_Success() throws Exception {
-        //Arrange
-        String eventId = "test-event-id-" + System.currentTimeMillis();
-        String eventType = "test-event-type";
-        Event event = new Event();
-        event.setEventType(eventType);
-        event.setItemId(eventId);
-
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setProfileId(TEST_PROFILE_ID);
-        contextRequest.setEvents(Arrays.asList(event));
-
-        //Act
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.addHeader(THIRD_PARTY_HEADER_NAME, UNOMI_KEY);
-        request.setEntity(new 
StringEntity(objectMapper.writeValueAsString(contextRequest), 
ContentType.APPLICATION_JSON));
-        TestUtils.executeContextJSONRequest(request);
-
-        keepTrying("Profile " + TEST_PROFILE_ID + " not found in the required 
time", () -> profileService.load(TEST_PROFILE_ID),
-                Objects::nonNull, DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-    }
-
-    @Test
-    public void testCreateEventWithPropertiesValidation_Success() throws 
Exception {
-        //Arrange
-        String eventId = "valid-event-id-" + System.currentTimeMillis();
-        String profileId = "valid-profile-id";
-        String eventType = FLOAT_PROPERTY_EVENT_TYPE;
-        Event event = new Event();
-        event.setEventType(eventType);
-        event.setItemId(eventId);
-        Map<String, Object> props = new HashMap<>();
-        props.put("floatProperty", 3.14159);
-        event.setProperties(props);
-
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setProfileId(profileId);
-        contextRequest.setEvents(Arrays.asList(event));
-
-        //Act
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.addHeader(THIRD_PARTY_HEADER_NAME, UNOMI_KEY);
-        request.setEntity(new 
StringEntity(objectMapper.writeValueAsString(contextRequest), 
ContentType.APPLICATION_JSON));
-        TestUtils.executeContextJSONRequest(request);
-
-        //Assert
-        event = keepTrying("Event not found", () -> 
eventService.getEvent(eventId), Objects::nonNull, DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-        assertEquals(eventType, event.getEventType());
-        assertEquals(3.14159, event.getProperty("floatProperty"));
-    }
-
-    @Test
-    public void testCreateEventWithPropertyValueValidation_Failure() throws 
Exception {
-        //Arrange
-        String eventId = "invalid-event-value-id-" + 
System.currentTimeMillis();
-        String profileId = "invalid-profile-id";
-        String eventType = FLOAT_PROPERTY_EVENT_TYPE;
-        Event event = new Event();
-        event.setEventType(eventType);
-        event.setItemId(eventId);
-        Map<String, Object> props = new HashMap<>();
-        props.put("floatProperty", "Invalid value");
-        event.setProperties(props);
-
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setProfileId(profileId);
-        contextRequest.setEvents(Arrays.asList(event));
-
-        //Act
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.addHeader(THIRD_PARTY_HEADER_NAME, UNOMI_KEY);
+        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));
-        TestUtils.executeContextJSONRequest(request);
+        assertEquals(TestUtils.executeContextJSONRequest(request, 
sessionId).getContextResponse().getProfileProperties().get("customProperty"), 
("concealedValue"));
 
-        //Assert
-        shouldBeTrueUntilEnd("Event should be null", () -> 
eventService.getEvent(eventId), Objects::isNull, DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-    }
-
-    @Test
-    public void testCreateEventWithPropertyNameValidation_Failure() throws 
Exception {
-        //Arrange
-        String eventId = "invalid-event-prop-id-" + System.currentTimeMillis();
-        String profileId = "invalid-profile-id";
-        Event event = new Event();
-        event.setEventType(FLOAT_PROPERTY_EVENT_TYPE);
-        event.setItemId(eventId);
-        Map<String, Object> props = new HashMap<>();
-        props.put("ffloatProperty", 3.14159);
-        event.setProperties(props);
+        // remove the concealed tag on the property type
+        customPropertyType.getMetadata().getSystemTags().remove("concealed");
+        profileService.deletePropertyType(customPropertyType.getItemId());
+        profileService.setPropertyType(customPropertyType);
 
-        ContextRequest contextRequest = new ContextRequest();
-        contextRequest.setProfileId(profileId);
-        contextRequest.setEvents(Arrays.asList(event));
-
-        //Act
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.addHeader(THIRD_PARTY_HEADER_NAME, UNOMI_KEY);
+        // Got it from all properties
+        contextRequest.setRequiredProfileProperties(Arrays.asList("*"));
         request.setEntity(new 
StringEntity(objectMapper.writeValueAsString(contextRequest), 
ContentType.APPLICATION_JSON));
-        TestUtils.executeContextJSONRequest(request);
-
-        //Assert
-        shouldBeTrueUntilEnd("Event should be null", () -> 
eventService.getEvent(eventId), Objects::isNull, DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
-    }
-
-    @Test
-    public void testOGNLVulnerability() throws Exception {
-
-        File vulnFile = new File("target/vuln-file.txt");
-        if (vulnFile.exists()) {
-            vulnFile.delete();
-        }
-        String vulnFileCanonicalPath = vulnFile.getCanonicalPath();
-        vulnFileCanonicalPath = vulnFileCanonicalPath.replace("\\", "\\\\"); 
// this is required for Windows support
-
-        Map<String, String> parameters = new HashMap<>();
-        parameters.put("VULN_FILE_PATH", vulnFileCanonicalPath);
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(
-                new 
StringEntity(getValidatedBundleJSON("security/ognl-payload-1.json", 
parameters), ContentType.APPLICATION_JSON));
-        TestUtils.executeContextJSONRequest(request);
-
-        shouldBeTrueUntilEnd("Vulnerability successfully executed ! File 
created at " + vulnFileCanonicalPath, vulnFile::exists,
-                exists -> exists == Boolean.FALSE, DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-    }
-
-    @Test
-    public void testMVELVulnerability() throws Exception {
-
-        File vulnFile = new File("target/vuln-file.txt");
-        if (vulnFile.exists()) {
-            vulnFile.delete();
-        }
-        String vulnFileCanonicalPath = vulnFile.getCanonicalPath();
-        vulnFileCanonicalPath = vulnFileCanonicalPath.replace("\\", "\\\\"); 
// this is required for Windows support
-
-        Map<String, String> parameters = new HashMap<>();
-        parameters.put("VULN_FILE_PATH", vulnFileCanonicalPath);
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(
-                new 
StringEntity(getValidatedBundleJSON("security/mvel-payload-1.json", 
parameters), ContentType.APPLICATION_JSON));
-        TestUtils.executeContextJSONRequest(request);
-
-        shouldBeTrueUntilEnd("Vulnerability successfully executed ! File 
created at " + vulnFileCanonicalPath, vulnFile::exists,
-                exists -> exists == Boolean.FALSE, DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-    }
-
-    @Test
-    public void testPersonalization() throws Exception {
-
-        Map<String, String> parameters = new HashMap<>();
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(new 
StringEntity(getValidatedBundleJSON("personalization.json", parameters), 
ContentType.APPLICATION_JSON));
-        TestUtils.RequestResponse response = 
TestUtils.executeContextJSONRequest(request);
-        assertEquals("Invalid response code", 200, response.getStatusCode());
-    }
-
-    @Test
-    public void testScorePersonalizationStrategy_Interests() throws Exception {
-        // Test request before adding interests to current profile.
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(new 
StringEntity(getValidatedBundleJSON("personalization-score-interests.json", 
null), ContentType.APPLICATION_JSON));
-        TestUtils.RequestResponse response = 
TestUtils.executeContextJSONRequest(request);
-        ContextResponse contextResponse = response.getContextResponse();
-        List<String> variants = 
contextResponse.getPersonalizations().get("perso-by-interest");
-        assertEquals("Invalid response code", 200, response.getStatusCode());
-        assertEquals("Perso should be empty, profile is empty", 0, 
variants.size());
-        variants = 
contextResponse.getPersonalizationResults().get("perso-by-interest").getContentIds();
-        assertEquals("Perso should be empty, profile is empty", 0, 
variants.size());
-
-        // set profile for matching
-        Profile profile = profileService.load(TEST_PROFILE_ID);
-        profile.setProperty("age", 30);
-        profileService.save(profile);
-        keepTrying("Profile " + TEST_PROFILE_ID + " not found in the required 
time", () -> profileService.load(TEST_PROFILE_ID),
-                savedProfile -> (savedProfile != null && 
savedProfile.getProperty("age").equals(30)), DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-
-        // check results of the perso now
-        request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(new 
StringEntity(getValidatedBundleJSON("personalization-score-interests.json", 
null), ContentType.APPLICATION_JSON));
-        response = TestUtils.executeContextJSONRequest(request);
-        contextResponse = response.getContextResponse();
-        variants = 
contextResponse.getPersonalizations().get("perso-by-interest");
-        assertEquals("Invalid response code", 200, response.getStatusCode());
-        assertEquals("Perso should contains the good number of variants", 1, 
variants.size());
-        assertEquals("Variant is not the expected one", 
"matching-fishing-interests-custom-score-100-variant-expected-score-120", 
variants.get(0));
-        variants = 
contextResponse.getPersonalizationResults().get("perso-by-interest").getContentIds();
-        assertEquals("Perso should contains the good number of variants", 1, 
variants.size());
-        assertEquals("Variant is not the expected one", 
"matching-fishing-interests-custom-score-100-variant-expected-score-120", 
variants.get(0));
-
-        // modify profile to add interests
-        profile = profileService.load(TEST_PROFILE_ID);
-        List<Map<String, Object>> interests = new ArrayList<>();
-        Map<String, Object> interest1 = new HashMap<>();
-        interest1.put("key", "cars");
-        interest1.put("value", 50);
-        interests.add(interest1);
-        Map<String, Object> interest2 = new HashMap<>();
-        interest2.put("key", "football");
-        interest2.put("value", 40);
-        interests.add(interest2);
-        Map<String, Object> interest3 = new HashMap<>();
-        interest3.put("key", "tennis");
-        interest3.put("value", 30);
-        interests.add(interest3);
-        Map<String, Object> interest4 = new HashMap<>();
-        interest4.put("key", "fishing");
-        interest4.put("value", 20);
-        interests.add(interest4);
-        profile.setProperty("interests", interests);
-        profileService.save(profile);
-        keepTrying("Profile " + TEST_PROFILE_ID + " not found in the required 
time", () -> profileService.load(TEST_PROFILE_ID),
-                savedProfile -> (savedProfile != null && 
savedProfile.getProperty("interests") != null), DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-
-        // re test now that profiles has interests
-        request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(new 
StringEntity(getValidatedBundleJSON("personalization-score-interests.json", 
null), ContentType.APPLICATION_JSON));
-        response = TestUtils.executeContextJSONRequest(request);
-        contextResponse = response.getContextResponse();
-        variants = 
contextResponse.getPersonalizations().get("perso-by-interest");
-        assertEquals("Invalid response code", 200, response.getStatusCode());
-        assertEquals("Perso should contains the good number of variants", 7, 
variants.size());
-        assertEquals("Variant is not the expected one", 
"matching-fishing-interests-custom-score-100-variant-expected-score-120", 
variants.get(0));
-        assertEquals("Variant is not the expected one", 
"matching-football-cars-interests-variant-expected-score-91", variants.get(1));
-        assertEquals("Variant is not the expected one", 
"not-matching-football-cars-interests-variant-expected-score-90", 
variants.get(2));
-        assertEquals("Variant is not the expected one", 
"not-matching-tennis-fishing-interests-variant-expected-score-50", 
variants.get(3));
-        assertEquals("Variant is not the expected one", 
"matching-football-interests-variant-expected-score-51", variants.get(4));
-        assertEquals("Variant is not the expected one", 
"matching-tennis-interests-variant-expected-score-31", variants.get(5));
-        assertEquals("Variant is not the expected one", 
"not-matching-tennis-interests-custom-score-100-variant-expected-score-30", 
variants.get(6));
-        variants = 
contextResponse.getPersonalizationResults().get("perso-by-interest").getContentIds();
-        assertEquals("Perso should contains the good number of variants", 7, 
variants.size());
-        assertEquals("Variant is not the expected one", 
"matching-fishing-interests-custom-score-100-variant-expected-score-120", 
variants.get(0));
-        assertEquals("Variant is not the expected one", 
"matching-football-cars-interests-variant-expected-score-91", variants.get(1));
-        assertEquals("Variant is not the expected one", 
"not-matching-football-cars-interests-variant-expected-score-90", 
variants.get(2));
-        assertEquals("Variant is not the expected one", 
"not-matching-tennis-fishing-interests-variant-expected-score-50", 
variants.get(3));
-        assertEquals("Variant is not the expected one", 
"matching-football-interests-variant-expected-score-51", variants.get(4));
-        assertEquals("Variant is not the expected one", 
"matching-tennis-interests-variant-expected-score-31", variants.get(5));
-        assertEquals("Variant is not the expected one", 
"not-matching-tennis-interests-custom-score-100-variant-expected-score-30", 
variants.get(6));
-    }
-
-    @Test
-    public void testRequireScoring() throws Exception {
-
-        Map<String, String> parameters = new HashMap<>();
-        String scoringSource = getValidatedBundleJSON("score1.json", 
parameters);
-        Scoring scoring = 
CustomObjectMapper.getObjectMapper().readValue(scoringSource, Scoring.class);
-        segmentService.setScoringDefinition(scoring);
-
-        keepTrying("Profile does not contains scores in the required time", () 
-> profileService.load(TEST_PROFILE_ID), storedProfile ->
-                storedProfile.getScores() != null && 
storedProfile.getScores().get("score1") != null, DEFAULT_TRYING_TIMEOUT, 
DEFAULT_TRYING_TRIES);
-
-        // first let's make sure everything works without the requireScoring 
parameter
-        parameters = new HashMap<>();
-        HttpPost request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(new 
StringEntity(getValidatedBundleJSON("withoutRequireScores.json", parameters), 
ContentType.APPLICATION_JSON));
-        TestUtils.RequestResponse response = 
TestUtils.executeContextJSONRequest(request);
-        assertEquals("Invalid response code", 200, response.getStatusCode());
-
-        assertNotNull("Context response should not be null", 
response.getContextResponse());
-        Map<String, Integer> scores = 
response.getContextResponse().getProfileScores();
-        assertNull("Context response should not contain scores", scores);
-
-        // now let's test adding it.
-        parameters = new HashMap<>();
-        request = new HttpPost(getFullUrl(CONTEXT_URL));
-        request.setEntity(new 
StringEntity(getValidatedBundleJSON("withRequireScores.json", parameters), 
ContentType.APPLICATION_JSON));
-        response = TestUtils.executeContextJSONRequest(request);
-        assertEquals("Invalid response code", 200, response.getStatusCode());
-
-        assertNotNull("Context response should not be null", 
response.getContextResponse());
-        scores = response.getContextResponse().getProfileScores();
-        assertNotNull("Context response should contain scores", scores);
-        assertNotNull("score1 not found in profile scores", 
scores.get("score1"));
-        assertEquals("score1 does not have expected value", 1, 
scores.get("score1").intValue());
-
-        segmentService.removeScoringDefinition(scoring.getItemId(), false);
-    }
-
-    @Test
-    public void test_no_ControlGroup() throws Exception {
-        performPersonalizationWithControlGroup(
-                null,
-                Collections.singletonList("no-condition"),
-                false,
-                false,
-                null,
-                null);
-    }
-
-    @Test
-    public void test_in_ControlGroup_profile_stored() throws Exception {
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("false", "100.0"),
-                Arrays.asList("first-name-missing", "no-condition"),
-                true,
-                true,
-                true,
-                null);
-
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("false", "0.0"),
-                Arrays.asList("first-name-missing", "no-condition"),
-                true,
-                true,
-                true,
-                null);
-    }
-
-    @Test
-    public void test_in_ControlGroup_session_stored() throws Exception {
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("true", "100.0"),
-                Arrays.asList("first-name-missing", "no-condition"),
-                true,
-                true,
-                null,
-                true);
-
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("true", "0.0"),
-                Arrays.asList("first-name-missing", "no-condition"),
-                true,
-                true,
-                null,
-                true);
-    }
-
-    @Test
-    public void test_out_ControlGroup_profile_stored() throws Exception {
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("false", "0.0"),
-                Collections.singletonList("no-condition"),
-                true,
-                false,
-                false,
-                null);
-
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("false", "100.0"),
-                Collections.singletonList("no-condition"),
-                true,
-                false,
-                false,
-                null);
-    }
-
-    @Test
-    public void test_out_ControlGroup_session_stored() throws Exception {
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("true", "0.0"),
-                Collections.singletonList("no-condition"),
-                true,
-                false,
-                null,
-                false);
-
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("true", "100.0"),
-                Collections.singletonList("no-condition"),
-                true,
-                false,
-                null,
-                false);
-    }
-
-    @Test
-    public void test_advanced_ControlGroup_test() throws Exception {
-        // STEP 1: start with no control group
-        performPersonalizationWithControlGroup(
-                null,
-                Collections.singletonList("no-condition"),
-                false,
-                false,
-                null,
-                null);
-
-        // STEP 2: then enable control group stored in profile
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("false", "100.0"),
-                Arrays.asList("first-name-missing", "no-condition"),
-                true,
-                true,
-                true,
-                null);
-
-        // STEP 3: then re disable control group
-        performPersonalizationWithControlGroup(
-                null,
-                Collections.singletonList("no-condition"),
-                false,
-                false,
-                /* We can see we still have old control group check stored in 
the profile */ true,
-                null);
-
-        // STEP 4: then re-enable control group, but session scoped this time, 
with a 0 percentage
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("true", "0.0"),
-                Collections.singletonList("no-condition"),
-                true,
-                false,
-                /* We can see we still have old control group check stored in 
the profile */ true,
-                /* And now we also have a status saved in the session */ 
false);
-
-        // STEP 5: then re-enable control group, but profile scoped this time, 
with a 0 percentage
-        //         We should be in control group because of the STEP 2, the 
current profile already contains a persisted status for the perso.
-        //         So even if current config is 0, old check already flagged 
current profile to be in the control group.
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("false", "0.0"),
-                Arrays.asList("first-name-missing", "no-condition"),
-                true,
-                true,
-                /* We can see we still have old control group check stored in 
the profile */ true,
-                /*  We can see we still have old control group check stored in 
the session too */ false);
-
-        // STEP 6: then re-enable control group, but session scoped this time, 
with a 100 percentage
-        //         We should not be in control group because of the STEP 4, 
the current session already contains a persisted status for the perso.
-        //         So even if current config is 100, old check already flagged 
current profile to not be in the control group.
-        performPersonalizationWithControlGroup(
-                generateControlGroupConfig("true", "100.0"),
-                Collections.singletonList("no-condition"),
-                true,
-                false,
-                /* We can see we still have old control group check stored in 
the profile */ true,
-                /*  We can see we still have old control group check stored in 
the session too */ false);
-
-        // STEP 7: then re disable control group
-        performPersonalizationWithControlGroup(
-                null,
-                Collections.singletonList("no-condition"),
-                false,
-                false,
-                /* We can see we still have old control group check stored in 
the profile */ true,
-                /*  We can see we still have old control group check stored in 
the session too */ false);
+        assertEquals(TestUtils.executeContextJSONRequest(request, 
sessionId).getContextResponse().getProfileProperties().get("customProperty"), 
("concealedValue"));
     }
 
     private void performPersonalizationWithControlGroup(Map<String, String> 
controlGroupConfig, List<String> expectedVariants,
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);
         }


Reply via email to