From c6eb75a940b578cd6cac41dca86336da8c3e1f76 Mon Sep 17 00:00:00 2001
From: clakech <cyril.lakech@adeoservices.com>
Date: Wed, 5 Jun 2013 11:50:17 +0200
Subject: [PATCH] add a feature to use redirect instead of popup -add a demo
 for this new feature

warning: I reuse the same callback url because I don't have access to the config
---
 example/demo_redirect.html | 33 +++++++++++++++++++++
 example/js/demo.js         | 44 ++++++++++++++++++++++++++++
 src/js/angularOauth.js     | 59 +++++++++++++++++++++++++++++++++++++-
 src/oauth2callback.html    |  2 +-
 4 files changed, 136 insertions(+), 2 deletions(-)
 create mode 100644 example/demo_redirect.html

diff --git a/example/demo_redirect.html b/example/demo_redirect.html
new file mode 100644
index 0000000..9d784d5
--- /dev/null
+++ b/example/demo_redirect.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html lang="en" ng-app="demoRedirect" ng-controller="DemoRedirectCtrl">
+<head>
+  <meta charset="utf-8">
+  <title>Client-side authentication demo with redirect</title>
+</head>
+<body>
+
+<div>
+  <div ng-show="accessToken" style="display: none">
+    <h1>You're authenticated!</h1>
+
+    <h2>Access token</h2>
+    <pre>{{accessToken}}</pre>
+
+    <div ng-show="expiresIn">
+      <h2>Expiry</h2>
+      <p>Expires in {{expiresIn}} seconds.</p>
+    </div>
+
+    <div ng-show="accessTokenVerified">
+        <h2>Access token verified</h2>
+    </div>
+  </div>
+</div>
+
+<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js"></script>
+
+<script src="js/demo.js"></script>
+<script src="../src/js/googleOauth.js"></script>
+<script src="../src/js/angularOauth.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/example/js/demo.js b/example/js/demo.js
index c7cade6..bff202e 100644
--- a/example/js/demo.js
+++ b/example/js/demo.js
@@ -42,4 +42,48 @@ angular.module('demo', ['googleOauth']).
           alert("Failed to get token from popup.");
         });
     };
+  });
+
+angular.module('demoRedirect', ['googleOauth']).
+
+  config(function(TokenProvider) {
+    // Demo configuration for the "angular-oauth demo" project on Google.
+    // Log in at will!
+
+    // Sorry about this way of getting a relative URL, powers that be.
+    var baseUrl = document.URL.replace('example/demo_redirect.html', '');
+
+    TokenProvider.extendConfig({
+      clientId: '191261111313.apps.googleusercontent.com',
+      redirectUri: baseUrl + 'src/oauth2callback.html',  // allow lunching demo from a mirror
+      scopes: ["https://www.googleapis.com/auth/userinfo.email"]
+    });
+  }).
+  controller('DemoRedirectCtrl', function($scope, $window, $location, Token) {
+
+    $scope.$on("$routeChangeStart", function () {
+      $scope.login();
+    });
+
+    $scope.login = function() {
+      $scope.accessToken = Token.get();
+      if ($scope.accessToken) {
+        // Success getting token.
+        // Verify the token before setting it, to avoid the confused deputy problem.
+        Token.verifyAsync($scope.accessToken).
+          then(function(data) {
+//            alert("verify token.");
+            $scope.accessTokenVerified = true;
+          }, function() {
+            alert("Failed to verify token.");
+        });
+      } else {
+        Token.extendConfig({state: $location.absUrl()});
+        var extraParams = {};
+        Token.getTokenWithRedirect(extraParams);
+      }
+    }
+
+    $scope.login();
+
   });
\ No newline at end of file
diff --git a/src/js/angularOauth.js b/src/js/angularOauth.js
index 7aef147..4bcba51 100644
--- a/src/js/angularOauth.js
+++ b/src/js/angularOauth.js
@@ -72,7 +72,8 @@ angular.module('angularOauth', []).
           response_type: RESPONSE_TYPE,
           client_id: config.clientId,
           redirect_uri: config.redirectUri,
-          scope: config.scopes.join(" ")
+          scope: config.scopes.join(" "),
+          state: config.state
         }
       };
 
@@ -184,6 +185,18 @@ angular.module('angularOauth', []).
           // TODO: reject deferred if the popup was closed without a message being delivered + maybe offer a timeout
 
           return deferred.promise;
+        },
+
+        extendConfig: function(configExtension) {
+          config = angular.extend(config, configExtension);
+        },
+
+        getTokenWithRedirect: function(extraParams) {
+
+            var params = angular.extend(getParams(), extraParams),
+                url = config.authorizationEndpoint + '?' + objectToQueryString(params);
+
+            $window.open(url, "_self");
         }
       }
     }
@@ -224,3 +237,47 @@ angular.module('angularOauth', []).
     window.opener.postMessage(params, "*");
     window.close();
   });
+
+  angular.module('angularOauthRedirect', ['angularOauth']).config(['TokenProvider', function (TokenProvider) {
+
+    // can't find any other way to avoid exception if I want to be able to use Token.set inside RedirectCtrl
+    TokenProvider.extendConfig({
+        clientId: 'test',
+        authorizationEndpoint: 'test',
+        redirectUri: 'test',
+        scopes: ['test'],
+        verifyFunc: 'test'
+    });
+
+  }]).
+
+  controller('RedirectCtrl', function($scope, $location, $window, $log, Token) {
+
+    /**
+     * TODO duplicate from CallbackCtrl
+     *
+     * Parses an escaped url query string into key-value pairs.
+     *
+     * (Copied from Angular.js in the AngularJS project.)
+     *
+     * @returns Object.<(string|boolean)>
+     */
+    function parseKeyValue(/**string*/keyValue) {
+      var obj = {}, key_value, key;
+      angular.forEach((keyValue || "").split('&'), function(keyValue){
+        if (keyValue) {
+          key_value = keyValue.split('=');
+          key = decodeURIComponent(key_value[0]);
+          obj[key] = angular.isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
+        }
+      });
+      return obj;
+    }
+
+    var queryString = $location.path().substring(1);  // preceding slash omitted
+    var params = parseKeyValue(queryString);
+
+    Token.set(params.access_token);
+
+    $window.open(params.state, "_self");
+  });
diff --git a/src/oauth2callback.html b/src/oauth2callback.html
index 6c52618..e21f9ad 100644
--- a/src/oauth2callback.html
+++ b/src/oauth2callback.html
@@ -1,5 +1,5 @@
 <!doctype html>
-<html lang="en" ng-app="angularOauth" ng-controller="CallbackCtrl">
+<html lang="en" ng-app="angularOauthRedirect" ng-controller="RedirectCtrl">
 <head>
   <meta charset="utf-8">
   <title>Receiving authentication</title>