changeset 60:be00b5be37d6

half-baked proof of concept for popup auth flow.
author Atul Varma <avarma@mozilla.com>
date Mon, 28 Jun 2010 22:31:00 -0700
parents ce0fb8a780a4
children 2d981c2a7f9a
files static-files/confirm.html static-files/js/api.js static-files/js/confirm.js static-files/js/server.js
diffstat 4 files changed, 165 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/static-files/confirm.html	Mon Jun 28 22:31:00 2010 -0700
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Mozilla Summit Confirmation</title>
+  <style>
+  body {
+    font-family: Helvetica, sans-serif;
+    font-size: 24pt;
+    width: 20em;
+    margin: 0 auto;
+  }
+
+  .origin {
+    font-weight: bold;
+  }
+
+  div.button {
+    cursor: pointer;
+    float: left;
+    padding: 1em;
+    margin: 1em;
+    background: blue;
+  }
+
+  div.button:hover {
+    background: yellow;
+  }
+  </style>
+</head>
+<body>
+<p>Do you want to allow <span class="origin"></span> to access your
+Mozilla Summit information?</p>
+<div class="button" id="no">Deny</div>
+<div class="button" id="yes">Allow</div>
+<script src="js/summit-idp.js"></script>
+<script src="js/api.js"></script>
+<script src="js/confirm.js"></script>
+</body>
+</html>
--- a/static-files/js/api.js	Mon Jun 28 19:05:02 2010 -0700
+++ b/static-files/js/api.js	Mon Jun 28 22:31:00 2010 -0700
@@ -100,7 +100,13 @@
         if (!(event.origin in originBrokers))
           originBrokers[event.origin] = brokerForOrigin(event.origin);
 
-        originBrokers[event.origin].onMessage(JSON.parse(event.data),
+        try {
+          var obj = JSON.parse(event.data);
+        } catch (e) {
+          return;
+        }
+
+        originBrokers[event.origin].onMessage(obj,
                                               event.origin,
                                               event.source);
       }
@@ -108,22 +114,23 @@
       window.addEventListener("message", onMessage, false);
     }
 
-    function GenericClient(origin, url) {
+    function GenericClient(origin, url, otherWindow) {
       var broker = new MessageBroker({}, postMessage);
-      var iframe = window.document.createElement("iframe");
-      var otherWindow;
       var queuedMessages = [];
 
-      iframe.src = url;
+      if (!otherWindow) {
+        var iframe = window.document.createElement("iframe");
+        iframe.src = url;
 
-      iframe.onload = function() {
-        otherWindow = iframe.contentWindow;
-        queuedMessages.forEach(postMessage);
-        queuedMessages = [];
-      };
+        iframe.onload = function() {
+          otherWindow = iframe.contentWindow;
+          queuedMessages.forEach(postMessage);
+          queuedMessages = [];
+        };
 
-      iframe.style.display = "none";
-      window.document.documentElement.appendChild(iframe);
+        iframe.style.display = "none";
+        window.document.documentElement.appendChild(iframe);
+      }
 
       function postMessage(msg) {
         if (!otherWindow)
@@ -133,9 +140,14 @@
       }
 
       function onMessage(event) {
-        if (event.origin == origin)
-          broker.onMessage(JSON.parse(event.data), event.origin,
-                           event.source);
+        if (event.origin == origin) {
+          try {
+            var obj = JSON.parse(event.data);
+          } catch (e) {
+            return;
+          }
+          broker.onMessage(obj, event.origin, event.source);
+        }
       }
 
       this.callCmd = broker.callCmd;
@@ -177,6 +189,24 @@
       }
 
       addMethod("getAllUsers");
+      self.authorize = function authorize(cb) {
+        var popup = window.open(url + "confirm.html", null,
+                                "width=640,height=480");
+        window.addEventListener(
+          "message",
+          function waitForReady(event) {
+            if (event.source == popup && event.data == "ready") {
+              window.removeEventListener("message", waitForReady, false);
+              var popupClient = new GenericClient(origin, null, popup);
+              popupClient.callCmd(
+                "requestAccess", null,
+                function(response) { popup.close(); cb(response); }
+              );
+            }
+          },
+          false
+        );
+      };
     }
 
     window.Summit = {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/static-files/js/confirm.js	Mon Jun 28 22:31:00 2010 -0700
@@ -0,0 +1,70 @@
+// -----------------------------------------------------------------------
+// ConfirmServer object
+// -----------------------------------------------------------------------
+// 
+// This sets up an in-browser "server" that can be accessed from other
+// windows via a postMessage API.
+
+(
+  function(window) {
+    var ConfirmServer = window.ConfirmServer = {};
+
+    var inRequest = false;
+    var config;
+
+    var handlers = {
+      requestAccess: function(options, cb, origin) {
+        if (inRequest) {
+          cb({error: "already in request"});
+          return;
+        }
+
+        config = Config.value;
+        inRequest = true;
+
+        if (config.state != "logged-in") {
+          cb({error: "not logged in"});
+          return;
+        }
+
+        if (!("trustedOrigins" in config)) {
+          config.trustedOrigins = [];
+        }
+
+        if (config.trustedOrigins.indexOf(origin) != -1)
+          cb({granted: true});
+        else {
+          var origins = window.document.querySelectorAll(".origin");
+          for (var i = 0; i < origins.length; i++)
+            origins[i].textContent = origin;
+
+          var no = window.document.getElementById("no");
+          var yes = window.document.getElementById("yes");
+
+          function detach() {
+            no.removeEventListener("click", onDeny, false);
+            yes.removeEventListener("click", onAccept, false);
+          }
+
+          function onDeny() {
+            detach();
+            cb({granted: false});
+          }
+
+          function onAccept() {
+            detach();
+            config.trustedOrigins.push(origin);
+            Config.setValue(config);
+            cb({granted: true});
+          }
+
+          no.addEventListener("click", onDeny, false);
+          yes.addEventListener("click", onAccept, false);
+        }
+      }
+    };
+
+    var server = new Summit.Server(handlers);
+    window.opener.postMessage("ready", "*");
+  }
+)(window);
--- a/static-files/js/server.js	Mon Jun 28 19:05:02 2010 -0700
+++ b/static-files/js/server.js	Mon Jun 28 22:31:00 2010 -0700
@@ -14,16 +14,20 @@
     var myOrigin = window.location.protocol + "//" + window.location.host;
     var handlers = {
       getAllUsers: function(options, cb, origin) {
-        if (origin != myOrigin) {
-          cb({error: "access denied"});
+        if (Config.value.state != "logged-in") {
+          cb({error: "not logged in"});
           return;
         }
 
-        // TODO: Add support for more origins.
-
-        if (Config.value.state != "logged-in") {
-          cb({error: "not logged in"});
-          return;
+        if (origin != myOrigin) {
+          if (!("trustedOrigins" in Config.value)) {
+            cb({error: "access denied"});
+            return;
+          }
+          if (Config.value.trustedOrigins.indexOf(origin) == -1) {
+            cb({error: "access denied"});
+            return;
+          }
         }
 
         if (Attendees.all) {