Repository: incubator-unomi
Updated Branches:
  refs/heads/feature-DMF-1343 d95aa89ad -> f694dacb2 (forced update)


UNOMI-98 Provide an example of integrating with an externally triggered login
- First commit of the login integration example

Signed-off-by: Serge Huber <shu...@apache.org>


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

Branch: refs/heads/feature-DMF-1343
Commit: ef8603824a887c6ebeb8cf56d27f8cd7c6593cd1
Parents: 4f4ade0
Author: Serge Huber <shu...@apache.org>
Authored: Mon May 29 13:57:03 2017 +0200
Committer: Serge Huber <shu...@apache.org>
Committed: Mon May 29 13:57:03 2017 +0200

----------------------------------------------------------------------
 samples/login-integration/pom.xml               |  64 +++++++++
 .../META-INF/cxs/rules/exampleLogin.json        |  34 +++++
 .../src/main/webapp/WEB-INF/web.xml             |  24 ++++
 .../src/main/webapp/index.html                  |  70 ++++++++++
 .../src/main/webapp/javascript/login-example.js | 136 +++++++++++++++++++
 samples/pom.xml                                 |   2 +-
 6 files changed, 329 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/ef860382/samples/login-integration/pom.xml
----------------------------------------------------------------------
diff --git a/samples/login-integration/pom.xml 
b/samples/login-integration/pom.xml
new file mode 100644
index 0000000..675807f
--- /dev/null
+++ b/samples/login-integration/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>samples</artifactId>
+        <groupId>org.apache.unomi</groupId>
+        <version>1.2.0-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>login-integration-sample</artifactId>
+    <name>Apache Unomi :: Samples :: External Login plugin</name>
+    <packaging>bundle</packaging>
+    <description>This is a simple Apache Unomi plugin.</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-api</artifactId>
+            <version>1.2.0-incubating-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet.jsp</groupId>
+            <artifactId>jsp-api</artifactId>
+            <version>2.1</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp</_wab>
+                        
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
+                        <Embed-Directory>WEB-INF/lib</Embed-Directory>
+                        <Web-ContextPath>/login</Web-ContextPath>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/ef860382/samples/login-integration/src/main/resources/META-INF/cxs/rules/exampleLogin.json
----------------------------------------------------------------------
diff --git 
a/samples/login-integration/src/main/resources/META-INF/cxs/rules/exampleLogin.json
 
b/samples/login-integration/src/main/resources/META-INF/cxs/rules/exampleLogin.json
new file mode 100644
index 0000000..6e3604b
--- /dev/null
+++ 
b/samples/login-integration/src/main/resources/META-INF/cxs/rules/exampleLogin.json
@@ -0,0 +1,34 @@
+{
+  "metadata": {
+    "id": "exampleLogin",
+    "name": "Example Login",
+    "description": "Copy event properties to profile properties on login"
+  },
+  "condition": {
+    "parameterValues": {
+      "subConditions": [
+        {
+          "parameterValues": {
+          },
+          "type": "loginEventCondition"
+        }
+      ],
+      "operator": "and"
+    },
+    "type": "booleanCondition"
+  },
+  "actions": [
+    {
+      "parameterValues": {
+        "mergeProfilePropertyValue": "eventProperty::target.properties(email)",
+        "mergeProfilePropertyName": "mergeIdentifier"
+      },
+      "type": "mergeProfilesOnPropertyAction"
+    },
+    {
+      "parameterValues": {
+      },
+      "type": "allEventToProfilePropertiesAction"
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/ef860382/samples/login-integration/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/samples/login-integration/src/main/webapp/WEB-INF/web.xml 
b/samples/login-integration/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..dc145f2
--- /dev/null
+++ b/samples/login-integration/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+<!--
+  ~ 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.
+  -->
+<web-app xmlns="http://java.sun.com/xml/ns/javaee";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd";
+         version="3.0">
+    <welcome-file-list>
+        <welcome-file>index.html</welcome-file>
+    </welcome-file-list>
+</web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/ef860382/samples/login-integration/src/main/webapp/index.html
----------------------------------------------------------------------
diff --git a/samples/login-integration/src/main/webapp/index.html 
b/samples/login-integration/src/main/webapp/index.html
new file mode 100644
index 0000000..8b03cbd
--- /dev/null
+++ b/samples/login-integration/src/main/webapp/index.html
@@ -0,0 +1,70 @@
+<!--
+~ 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.
+-->
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>Login integration example</title>
+    <!-- Latest compiled and minified CSS -->
+    <link rel="stylesheet" 
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
+          
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
 crossorigin="anonymous">
+    <!-- Optional theme -->
+    <link rel="stylesheet" 
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css";
+          
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
 crossorigin="anonymous">
+    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
+    <script 
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js";></script>
+    <!-- Latest compiled and minified JavaScript -->
+    <script 
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js";
+            
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
+            crossorigin="anonymous"></script>
+    <script src="javascript/login-example.js"></script>
+</head>
+<body>
+<div class="container">
+    <h1>Login integration example</h1>
+    <p>This is a small example of integrating Apache Unomi with an event login 
in order to merge profile based on emails
+    as merge keys (see associated rule file in 
src/main/resources/META-INF/cxs/rules/exampleLogin.json).</p>
+    <p>Important: note that login events should normally always be sent from 
the server performing the login, not through
+    Javascript for security reasons. Here we provide this type of example only 
for brievety and clarity.</p>
+    <div id="alert_placeholder"></div>
+    <form id="loginForm">
+        <div class="form-group">
+            <label for="firstname">First name</label>
+            <input type="text" name="firstName" id="firstname" 
class="form-control"
+                   placeholder="Enter your first name here"/>
+        </div>
+        <div class="form-group">
+            <label for="lastname">Last name</label>
+            <input type="text" name="lastName" id="lastname" 
class="form-control"
+                   placeholder="Enter your last name here"/>
+        </div>
+        <div class="form-group">
+            <label for="email">Email</label>
+            <input type="text" name="email" id="email" class="form-control" 
placeholder="Enter your email here"
+            >
+        </div>
+        <div class="form-group">
+            <label for="email">Password</label>
+            <input type="password" name="password" id="password" 
class="form-control"
+                   placeholder="Enter your password here">
+        </div>
+        <button id="loginButton" type="submit" class="btn 
btn-default">Login</button>
+    </form>
+</div>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/ef860382/samples/login-integration/src/main/webapp/javascript/login-example.js
----------------------------------------------------------------------
diff --git 
a/samples/login-integration/src/main/webapp/javascript/login-example.js 
b/samples/login-integration/src/main/webapp/javascript/login-example.js
new file mode 100644
index 0000000..3c01113
--- /dev/null
+++ b/samples/login-integration/src/main/webapp/javascript/login-example.js
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+(function () {
+
+    // We use this method to generate unique sessions IDs
+    function generateGuid() {
+        function s4() {
+            return Math.floor((1 + Math.random()) * 0x10000)
+                .toString(16)
+                .substring(1);
+        }
+
+        return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
+            s4() + '-' + s4() + s4() + s4();
+    }
+
+    // -- COOKIE HELPER METHODS ---
+
+    function createCookie(name, value, days) {
+        var expires;
+
+        if (days) {
+            var date = new Date();
+            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
+            expires = "; expires=" + date.toGMTString();
+        } else {
+            expires = "";
+        }
+        document.cookie = encodeURIComponent(name) + "=" + 
encodeURIComponent(value) + expires + "; path=/";
+    }
+
+    function readCookie(name) {
+        var nameEQ = encodeURIComponent(name) + "=";
+        var ca = document.cookie.split(';');
+        for (var i = 0; i < ca.length; i++) {
+            var c = ca[i];
+            while (c.charAt(0) === ' ') c = c.substring(1, c.length);
+            if (c.indexOf(nameEQ) === 0) return 
decodeURIComponent(c.substring(nameEQ.length, c.length));
+        }
+        return null;
+    }
+
+    function eraseCookie(name) {
+        createCookie(name, "", -1);
+    }
+
+    // -- BOOTSTRAP HELPER METHODS ---
+
+    bootstrapAlert = {};
+    bootstrapAlert.success = function (message) {
+        $('#alert_placeholder').html('<div class="alert alert-success"><a 
class="close" data-dismiss="alert">×</a><span>' + message + '</span></div>')
+    };
+    bootstrapAlert.danger = function (message) {
+        $('#alert_placeholder').html('<div class="alert alert-danger"><a 
class="close" data-dismiss="alert">×</a><span>' + message + '</span></div>')
+    };
+
+    $(document).ready(function () {
+
+        // first we check if we have an existing session ID cookie, if not we 
generate a new session identifier and
+        // store it in the cookie.
+        var unomiSessionId = readCookie('unomi-session-id');
+        if (!unomiSessionId) {
+            unomiSessionId = generateGuid();
+            console.log("No existing session cookie found, creating a new one 
with value " + unomiSessionId);
+            createCookie('unomi-session-id', unomiSessionId, 1);
+        }
+        console.log("Setting up form listener...");
+        $("#loginForm").submit(function (event) {
+            var email = $('#email').val();
+            var firstName = $('#firstname').val();
+            var lastName = $('#lastname').val();
+            var password = $('#password').val();
+            if (password != 'test1234') {
+                bootstrapAlert.danger("Wrong password (default is : 
test1234)");
+                event.preventDefault();
+                return false;
+            }
+            var contextRequest = {
+                source: { // the source is required for the request to be 
process properly
+                    itemId: location.pathname,
+                    itemType: 'webpage',
+                    scope: 'test' // the scope is used to regroup events and 
sessions into sub-groups (eg sites)
+                },
+                events: [{ // here we provide a simple login event, but as 
this is actually an array we could provide other events at the same time (page 
view, clicks, mouse movements, ...)
+                    eventType: "login",
+                    properties: {},
+                    target: {
+                        itemId: email,
+                        itemType: "exampleUser",
+                        properties: {
+                            preferredLanguage: "en",
+                            email: email,
+                            firstName: firstName,
+                            lastName: lastName
+                        }
+                    }
+                }],
+                requiredProfileProperties: ['*'], // this tells Unomi to send 
us back all the profile properties (by default none are returned)
+                requiredSessionProperties: ['*']  // this tells Unomi to send 
us back all the session properties (by default none are returned)
+            };
+            // now let's perform the actual call to Apache Unomi, asking it to 
process the events and give us back the updated (or created) profile.
+            // as we have a rule listening to a login event, it will be 
executed and its actions will be processed.
+            $.ajax({
+                url: "http://localhost:8181/context.json?sessionId="; + 
unomiSessionId,
+                type: 'POST',
+                data: JSON.stringify(contextRequest), // make sure you sent 
JSON and not form-encoded, otherwise Unomi will generate an error
+                contentType: 'application/json; charset=utf-8',
+                dataType: 'json',
+                async: false,
+                success: function (data) {
+                    console.log("Unomi response:", data);
+                    bootstrapAlert.success("Successfully sent login event to 
Apache Unomi ! (profileId=" + data.profileId + ",properties.email=" + 
data.profileProperties.email + ",nbOfVisits=" + 
data.profileProperties.nbOfVisits + ")");
+                }
+            });
+            event.preventDefault();
+            return false;
+        });
+    });
+
+})();
+

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/ef860382/samples/pom.xml
----------------------------------------------------------------------
diff --git a/samples/pom.xml b/samples/pom.xml
index 8941427..67e0d6f 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -28,7 +28,7 @@
     <packaging>pom</packaging>
     <modules>
         <module>tweet-button-plugin</module>
+        <module>login-integration</module>
     </modules>
 
-
 </project>
\ No newline at end of file

Reply via email to