You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by dr...@apache.org on 2016/02/05 13:12:26 UTC

[2/4] incubator-unomi git commit: UNOMI-15 : Use token to authenticate third party servers

UNOMI-15 : Use token to authenticate third party servers


Project: http://git-wip-us.apache.org/repos/asf/incubator-unomi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-unomi/commit/c9f24715
Tree: http://git-wip-us.apache.org/repos/asf/incubator-unomi/tree/c9f24715
Diff: http://git-wip-us.apache.org/repos/asf/incubator-unomi/diff/c9f24715

Branch: refs/heads/master
Commit: c9f2471561362f09c08dea91ae9578a25bebbc19
Parents: 8f4c6d0
Author: Thomas Draier <dr...@apache.org>
Authored: Wed Feb 3 14:32:19 2016 +0100
Committer: Thomas Draier <dr...@apache.org>
Committed: Fri Feb 5 11:32:20 2016 +0100

----------------------------------------------------------------------
 .../apache/unomi/api/services/EventService.java | 14 ++++
 kar/src/main/feature/feature.xml                |  1 +
 services/pom.xml                                |  7 ++
 .../services/services/EventServiceImpl.java     | 71 ++++++++++++++++++--
 .../services/services/ThirdPartyServer.java     | 67 ++++++++++++++++++
 .../resources/OSGI-INF/blueprint/blueprint.xml  | 14 +++-
 .../resources/org.apache.unomi.thirdparty.cfg   | 20 ++++++
 .../org/apache/unomi/web/ContextServlet.java    | 24 +++++--
 .../unomi/web/EventsCollectorServlet.java       | 13 ++--
 .../resources/OSGI-INF/blueprint/blueprint.xml  |  1 +
 10 files changed, 213 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/api/src/main/java/org/apache/unomi/api/services/EventService.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/unomi/api/services/EventService.java b/api/src/main/java/org/apache/unomi/api/services/EventService.java
index fe81130..5e74e83 100644
--- a/api/src/main/java/org/apache/unomi/api/services/EventService.java
+++ b/api/src/main/java/org/apache/unomi/api/services/EventService.java
@@ -56,6 +56,20 @@ public interface EventService {
     int send(Event event);
 
     /**
+     * Check if the sender is allowed to sent the speecified event. Restricted event must be explicitely allowed for a sender.
+     * @param event
+     * @param thirdPartyId
+     * @return
+     */
+    boolean isEventAllowed(Event event, String thirdPartyId);
+
+    /**
+     * Get the third party server name, if the request is originated from a known peer
+     * @return
+     */
+    String authenticateThirdPartyServer(String key, String ip);
+
+    /**
      * Retrieves the list of available event properties.
      *
      * @return a list of available event properties

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/kar/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/kar/src/main/feature/feature.xml b/kar/src/main/feature/feature.xml
index 72e3e7f..5e63b8b 100644
--- a/kar/src/main/feature/feature.xml
+++ b/kar/src/main/feature/feature.xml
@@ -27,6 +27,7 @@
         <configfile finalname="/etc/org.apache.unomi.persistence.elasticsearch.cfg">mvn:org.apache.unomi/unomi-persistence-elasticsearch-core/${project.version}/cfg/elasticsearchcfg</configfile>
         <configfile finalname="/etc/org.apache.unomi.plugins.request.cfg">mvn:org.apache.unomi/unomi-plugins-request/${project.version}/cfg/requestcfg</configfile>
         <configfile finalname="/etc/org.apache.unomi.services.cfg">mvn:org.apache.unomi/unomi-services/${project.version}/cfg/servicescfg</configfile>
+        <configfile finalname="/etc/org.apache.unomi.thirdparty.cfg">mvn:org.apache.unomi/unomi-services/${project.version}/cfg/thirdpartycfg</configfile>
         <configfile finalname="/etc/org.apache.unomi.geonames.cfg">mvn:org.apache.unomi/cxs-geonames-services/${project.version}/cfg/geonamescfg</configfile>
         <configfile finalname="/etc/elasticsearch.yml">mvn:org.apache.unomi/unomi-persistence-elasticsearch-core/${project.version}/yml/elasticsearchconfig</configfile>
         <bundle start-level="75">mvn:commons-io/commons-io/2.4</bundle>

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/services/pom.xml
----------------------------------------------------------------------
diff --git a/services/pom.xml b/services/pom.xml
index ea3efce..03fd7b7 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -174,6 +174,13 @@
                                     <type>cfg</type>
                                     <classifier>servicescfg</classifier>
                                 </artifact>
+                                <artifact>
+                                    <file>
+                                        src/main/resources/org.apache.unomi.thirdparty.cfg
+                                    </file>
+                                    <type>cfg</type>
+                                    <classifier>thirdpartycfg</classifier>
+                                </artifact>
                             </artifacts>
                         </configuration>
                     </execution>

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/services/src/main/java/org/apache/unomi/services/services/EventServiceImpl.java
----------------------------------------------------------------------
diff --git a/services/src/main/java/org/apache/unomi/services/services/EventServiceImpl.java b/services/src/main/java/org/apache/unomi/services/services/EventServiceImpl.java
index 4b207d9..22cdcda 100644
--- a/services/src/main/java/org/apache/unomi/services/services/EventServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/services/EventServiceImpl.java
@@ -24,38 +24,72 @@ import org.apache.unomi.api.conditions.Condition;
 import org.apache.unomi.api.services.DefinitionsService;
 import org.apache.unomi.api.services.EventListenerService;
 import org.apache.unomi.api.services.EventService;
-import org.apache.unomi.api.services.ProfileService;
 import org.apache.unomi.persistence.spi.PersistenceService;
 import org.apache.unomi.persistence.spi.aggregate.TermsAggregate;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.*;
 
 public class EventServiceImpl implements EventService {
+    private static final Logger logger = LoggerFactory.getLogger(SegmentServiceImpl.class.getName());
 
     private List<EventListenerService> eventListeners = new ArrayList<EventListenerService>();
 
     private PersistenceService persistenceService;
 
-    private ProfileService profileService;
-
     private DefinitionsService definitionsService;
 
     private BundleContext bundleContext;
 
     private Set<String> predefinedEventTypeIds = new LinkedHashSet<String>();
 
+    private Set<String> restrictedEventTypeIds = new LinkedHashSet<String>();
+
+    private Map<String, ThirdPartyServer> thirdPartyServers = new HashMap<>();
+
+    public void setThirdPartyConfiguration(Map<String,String> thirdPartyConfiguration) {
+        this.thirdPartyServers = new HashMap<>();
+        for (Map.Entry<String, String> entry : thirdPartyConfiguration.entrySet()) {
+            String[] keys = StringUtils.split(entry.getKey(),'.');
+            if (keys[0].equals("thirdparty")) {
+                if (!thirdPartyServers.containsKey(keys[1])) {
+                    thirdPartyServers.put(keys[1], new ThirdPartyServer(keys[1]));
+                }
+                ThirdPartyServer thirdPartyServer = thirdPartyServers.get(keys[1]);
+                if (keys[2].equals("allowedEvents")) {
+                    thirdPartyServer.setAllowedEvents(new HashSet<>(Arrays.asList(StringUtils.split(entry.getValue(), ','))));
+                } else if (keys[2].equals("key")) {
+                    thirdPartyServer.setKey(entry.getValue());
+                } else if (keys[2].equals("ipAddresses")) {
+                    Set<InetAddress> inetAddresses = new HashSet<>();
+                    for (String ip : StringUtils.split(entry.getValue(), ',')) {
+                        try {
+                            inetAddresses.add(InetAddress.getByName(ip));
+                        } catch (UnknownHostException e) {
+                            logger.error("Cannot resolve address",e);
+                        }
+                    }
+                    thirdPartyServer.setIpAddresses(inetAddresses);
+                }
+            }
+        }
+    }
+
     public void setPredefinedEventTypeIds(Set<String> predefinedEventTypeIds) {
         this.predefinedEventTypeIds = predefinedEventTypeIds;
     }
 
-    public void setPersistenceService(PersistenceService persistenceService) {
-        this.persistenceService = persistenceService;
+    public void setRestrictedEventTypeIds(Set<String> restrictedEventTypeIds) {
+        this.restrictedEventTypeIds = restrictedEventTypeIds;
     }
 
-    public void setProfileService(ProfileService profileService) {
-        this.profileService = profileService;
+    public void setPersistenceService(PersistenceService persistenceService) {
+        this.persistenceService = persistenceService;
     }
 
     public void setDefinitionsService(DefinitionsService definitionsService) {
@@ -66,6 +100,29 @@ public class EventServiceImpl implements EventService {
         this.bundleContext = bundleContext;
     }
 
+    public boolean isEventAllowed(Event event, String thirdPartyId) {
+        if (restrictedEventTypeIds.contains(event.getEventType())) {
+            return thirdPartyServers.containsKey(thirdPartyId) && thirdPartyServers.get(thirdPartyId).getAllowedEvents().contains(event.getEventType());
+        }
+        return true;
+    }
+
+    public String authenticateThirdPartyServer(String key, String ip) {
+        if (key != null) {
+            for (Map.Entry<String, ThirdPartyServer> entry : thirdPartyServers.entrySet()) {
+                ThirdPartyServer server = entry.getValue();
+                try {
+                    if (server.getKey().equals(key) && server.getIpAddresses().contains(InetAddress.getByName(ip))) {
+                        return server.getId();
+                    }
+                } catch (UnknownHostException e) {
+                    logger.error("Cannot resolve address",e);
+                }
+            }
+        }
+        return null;
+    }
+
     public int send(Event event) {
         if (event.isPersistent()) {
             persistenceService.save(event);

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/services/src/main/java/org/apache/unomi/services/services/ThirdPartyServer.java
----------------------------------------------------------------------
diff --git a/services/src/main/java/org/apache/unomi/services/services/ThirdPartyServer.java b/services/src/main/java/org/apache/unomi/services/services/ThirdPartyServer.java
new file mode 100644
index 0000000..c4587d7
--- /dev/null
+++ b/services/src/main/java/org/apache/unomi/services/services/ThirdPartyServer.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.unomi.services.services;
+
+import java.net.InetAddress;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Representation of a third party server, containing key, ip address, and allowed events
+ */
+public class ThirdPartyServer {
+    private String id;
+
+    private String key;
+
+    private Set<InetAddress> ipAddresses;
+
+    private Set<String> allowedEvents = new HashSet<>();
+
+    public ThirdPartyServer(String id) {
+        this.id = id;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public Set<InetAddress> getIpAddresses() {
+        return ipAddresses;
+    }
+
+    public Set<String> getAllowedEvents() {
+        return allowedEvents;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public void setIpAddresses(Set<InetAddress> ipAddresses) {
+        this.ipAddresses = ipAddresses;
+    }
+
+    public void setAllowedEvents(Set<String> allowedEvents) {
+        this.allowedEvents = allowedEvents;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index 7d3bc87..2af329c 100644
--- a/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -46,7 +46,6 @@
 
     <bean id="eventServiceImpl" class="org.apache.unomi.services.services.EventServiceImpl">
         <property name="persistenceService" ref="persistenceService"/>
-        <property name="profileService" ref="profileServiceImpl"/>
         <property name="definitionsService" ref="definitionsServiceImpl"/>
         <property name="bundleContext" ref="blueprintBundleContext"/>
         <property name="predefinedEventTypeIds">
@@ -58,6 +57,19 @@
                 <value>profileUpdated</value>
             </set>
         </property>
+        <property name="restrictedEventTypeIds">
+            <set>
+                <value>login</value>
+                <value>facebookLogin</value>
+                <value>sessionCreated</value>
+                <value>sessionReassigned</value>
+                <value>profileUpdated</value>
+                <value>ruleFired</value>
+            </set>
+        </property>
+        <property name="thirdPartyConfiguration">
+            <cm:cm-properties persistent-id="org.apache.unomi.thirdparty" update="true" />
+        </property>
     </bean>
     <service id="eventService" ref="eventServiceImpl" auto-export="interfaces"/>
 

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/services/src/main/resources/org.apache.unomi.thirdparty.cfg
----------------------------------------------------------------------
diff --git a/services/src/main/resources/org.apache.unomi.thirdparty.cfg b/services/src/main/resources/org.apache.unomi.thirdparty.cfg
new file mode 100644
index 0000000..06c3278
--- /dev/null
+++ b/services/src/main/resources/org.apache.unomi.thirdparty.cfg
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+thirdparty.jahia.key=670c26d1cc413346c3b2fd9ce65dab41
+thirdparty.jahia.ipAddresses=127.0.0.1,::1
+thirdparty.jahia.allowedEvents=login,download

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
----------------------------------------------------------------------
diff --git a/wab/src/main/java/org/apache/unomi/web/ContextServlet.java b/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
index 2e43302..5b8b333 100644
--- a/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
+++ b/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
@@ -23,6 +23,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.unomi.api.*;
 import org.apache.unomi.api.conditions.Condition;
 import org.apache.unomi.api.services.EventService;
+import org.apache.unomi.api.services.PrivacyService;
 import org.apache.unomi.api.services.ProfileService;
 import org.apache.unomi.api.services.RulesService;
 import org.apache.unomi.persistence.spi.CustomObjectMapper;
@@ -53,6 +54,7 @@ public class ContextServlet extends HttpServlet {
     private ProfileService profileService;
     private EventService eventService;
     private RulesService rulesService;
+    private PrivacyService privacyService;
 
     private String profileIdCookieName = "context-profile-id";
     private String profileIdCookieDomain;
@@ -253,17 +255,25 @@ public class ContextServlet extends HttpServlet {
 
     private int handleRequest(ContextRequest contextRequest, Profile profile, Session session, ContextResponse data, ServletRequest request, ServletResponse response, Date timestamp)
             throws IOException {
+        List<String> filteredEventTypes = privacyService.getFilteredEventTypes(profile.getItemId());
+
+        String thirdPartyId = eventService.authenticateThirdPartyServer(((HttpServletRequest)request).getHeader("X-Unomi-Peer"), request.getRemoteAddr());
+
         int changes = EventService.NO_CHANGE;
         // execute provided events if any
         if(contextRequest.getEvents() != null && !(profile instanceof Persona)) {
             for (Event event : contextRequest.getEvents()){
                 if(event.getEventType() != null) {
-                    Event eventToSend;
-                    if(event.getProperties() != null){
-                        eventToSend = new Event(event.getEventType(), session, profile, contextRequest.getSource().getScope(), event.getSource(), event.getTarget(), event.getProperties(), timestamp);
-                    } else {
-                        eventToSend = new Event(event.getEventType(), session, profile, contextRequest.getSource().getScope(), event.getSource(), event.getTarget(), timestamp);
+                    Event eventToSend = new Event(event.getEventType(), session, profile, contextRequest.getSource().getScope(), event.getSource(), event.getTarget(), event.getProperties(), timestamp);
+                    if (!eventService.isEventAllowed(event, thirdPartyId)) {
+                        logger.debug("Event is not allowed : {}", event.getEventType());
+                        continue;
+                    }
+                    if (filteredEventTypes != null && filteredEventTypes.contains(event.getEventType())) {
+                        logger.debug("Profile is filtering event type {}", event.getEventType());
+                        continue;
                     }
+
                     event.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, request);
                     event.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, response);
                     logger.debug("Received event " + event.getEventType() + " for profile=" + profile.getItemId() + " session=" + session.getItemId() + " target=" + event.getTarget() + " timestamp=" + timestamp);
@@ -365,4 +375,8 @@ public class ContextServlet extends HttpServlet {
     public void setProfileIdCookieDomain(String profileIdCookieDomain) {
         this.profileIdCookieDomain = profileIdCookieDomain;
     }
+
+    public void setPrivacyService(PrivacyService privacyService) {
+        this.privacyService = privacyService;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java
----------------------------------------------------------------------
diff --git a/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java b/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java
index c34ead2..24aa727 100644
--- a/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java
+++ b/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java
@@ -35,6 +35,7 @@ import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 public class EventsCollectorServlet extends HttpServlet {
     private static final Logger logger = LoggerFactory.getLogger(EventsCollectorServlet.class.getName());
@@ -130,16 +131,16 @@ public class EventsCollectorServlet extends HttpServlet {
             return;
         }
 
+        String thirdPartyId = eventService.authenticateThirdPartyServer(((HttpServletRequest)request).getHeader("X-Unomi-Peer"), request.getRemoteAddr());
+
         int changes = 0;
         for (Event event : events.getEvents()){
             if(event.getEventType() != null){
-                Event eventToSend;
-                if(event.getProperties() != null){
-                    eventToSend = new Event(event.getEventType(), session, profile, event.getScope(), event.getSource(), event.getTarget(), event.getProperties(), timestamp);
-                } else {
-                    eventToSend = new Event(event.getEventType(), session, profile, event.getScope(), event.getSource(), event.getTarget(), timestamp);
+                Event eventToSend = new Event(event.getEventType(), session, profile, event.getScope(), event.getSource(), event.getTarget(), event.getProperties(), timestamp);
+                if (!eventService.isEventAllowed(event, thirdPartyId)) {
+                    logger.debug("Event is not allowed : {}", event.getEventType());
+                    continue;
                 }
-
                 if (filteredEventTypes != null && filteredEventTypes.contains(event.getEventType())) {
                     logger.debug("Profile is filtering event type {}", event.getEventType());
                     continue;

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/c9f24715/wab/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/wab/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/wab/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index eab2e9a..6103121 100644
--- a/wab/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/wab/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -38,6 +38,7 @@
         <property name="profileService" ref="profileService"/>
         <property name="eventService" ref="eventService"/>
         <property name="rulesService" ref="rulesService"/>
+        <property name="privacyService" ref="privacyService" />
         <property name="profileIdCookieDomain" value="${web.contextserver.domain}" />
     </bean>