Repository: zeppelin
Updated Branches:
  refs/heads/master 2a4d3699a -> 97dfb8986


[ZEPPELIN-2147] zeppelin should redirect to login page after browser session 
expires

### What is this PR for?
Zeppelin should redirect to login page after browser session expires

### What type of PR is it?
[Bug Fix]

### What is the Jira issue?
* 
[https://issues.apache.org/jira/browse/ZEPPELIN-2147](https://issues.apache.org/jira/browse/ZEPPELIN-2147)

### How should this be tested?
 - Open any Zeppelin's notebook on a browser
 - Restart zeppelin server
 - now as soon as next web-socket message or API request is sent to server that 
returns either "ticket is invalid" or 405. This should get redirected to login 
page.
 - On successful login it should take user back to the page from where he was 
coming from.

### Screenshots (if appropriate)
![zeppelin-2147](https://cloud.githubusercontent.com/assets/674497/23250873/ec27b6e6-f9d0-11e6-8e6f-75e97f2449b1.gif)

### Questions:
* Does the licenses files need update? N/A
* Is there breaking changes for older versions? N/A
* Does this needs documentation? N/A

Author: Prabhjyot Singh <prabhjyotsi...@gmail.com>

Closes #2058 from prabhjyotsingh/ZEPPELIN-2147 and squashes the following 
commits:

27bc361 [Prabhjyot Singh] user $timeout with $location
9189089 [Prabhjyot Singh] in case of session lost or logout, show login window


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/97dfb898
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/97dfb898
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/97dfb898

Branch: refs/heads/master
Commit: 97dfb898666ea186d9bb5fbe85dae4c1aa15bf25
Parents: 2a4d369
Author: Prabhjyot Singh <prabhjyotsi...@gmail.com>
Authored: Fri Feb 24 13:01:10 2017 +0530
Committer: Prabhjyot Singh <prabhjyotsi...@gmail.com>
Committed: Mon Feb 27 12:10:40 2017 +0530

----------------------------------------------------------------------
 .../apache/zeppelin/socket/NotebookServer.java  |  4 +--
 zeppelin-web/src/app/app.js                     | 20 ++++++++++++-
 .../src/components/login/login.controller.js    | 30 ++++++++++++++++++--
 .../websocketEvents/websocketEvents.factory.js  |  2 ++
 .../zeppelin/notebook/socket/Message.java       |  1 +
 5 files changed, 52 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/97dfb898/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java 
b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
index 73e0d5b..d9cbca8 100644
--- 
a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
+++ 
b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
@@ -200,9 +200,9 @@ public class NotebookServer extends WebSocketServlet
               messagereceived.ticket, ticket);
         } else {
           if (!messagereceived.op.equals(OP.PING)) {
-            conn.send(serializeMessage(new Message(OP.ERROR_INFO).put("info",
+            conn.send(serializeMessage(new 
Message(OP.SESSION_LOGOUT).put("info",
                 "Your ticket is invalid possibly due to server restart. "
-                    + "Please refresh the page and login again.")));
+                    + "Please login again.")));
           }
         }
         return;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/97dfb898/zeppelin-web/src/app/app.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/app.js b/zeppelin-web/src/app/app.js
index f68b3da..40b19c1 100644
--- a/zeppelin-web/src/app/app.js
+++ b/zeppelin-web/src/app/app.js
@@ -96,7 +96,7 @@ var zeppelinWebApp = angular.module('zeppelinWebApp', [
       .when('/helium', {
         templateUrl: 'app/helium/helium.html',
         controller: 'HeliumCtrl'
-      })    
+      })
       .when('/configuration', {
         templateUrl: 'app/configuration/configuration.html',
         controller: 'ConfigurationCtrl'
@@ -116,6 +116,24 @@ var zeppelinWebApp = angular.module('zeppelinWebApp', [
       timeout: 6000
     });
   })
+
+  //handel logout on API failure
+  .config(function ($httpProvider, $provide) {
+    $provide.factory('httpInterceptor', function ($q, $rootScope) {
+      return {
+        'responseError': function (rejection) {
+          if (rejection.status === 405) {
+            var data = {};
+            data.info = '';
+            $rootScope.$broadcast('session_logout', data);
+          }
+          $rootScope.$broadcast('httpResponseError', rejection);
+          return $q.reject(rejection);
+        }
+      };
+    });
+    $httpProvider.interceptors.push('httpInterceptor');
+  })
   .constant('TRASH_FOLDER_ID', '~Trash');
 
 function auth() {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/97dfb898/zeppelin-web/src/components/login/login.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/login/login.controller.js 
b/zeppelin-web/src/components/login/login.controller.js
index 8b761a4..370466e 100644
--- a/zeppelin-web/src/components/login/login.controller.js
+++ b/zeppelin-web/src/components/login/login.controller.js
@@ -14,7 +14,7 @@
 
 angular.module('zeppelinWebApp').controller('LoginCtrl', LoginCtrl);
 
-function LoginCtrl($scope, $rootScope, $http, $httpParamSerializer, 
baseUrlSrv) {
+function LoginCtrl($scope, $rootScope, $http, $httpParamSerializer, 
baseUrlSrv, $location, $timeout) {
   'ngInject';
 
   $scope.SigningIn = false;
@@ -37,6 +37,17 @@ function LoginCtrl($scope, $rootScope, $http, 
$httpParamSerializer, baseUrlSrv)
       angular.element('#loginModal').modal('toggle');
       $rootScope.$broadcast('loginSuccess', true);
       $rootScope.userName = $scope.loginParams.userName;
+      $scope.SigningIn = false;
+
+      //redirect to the page from where the user originally was
+      if ($location.search() && $location.search()['ref']) {
+        $timeout(function() {
+          var redirectLocation = $location.search()['ref'];
+          $location.$$search = {};
+          $location.path(redirectLocation);
+        }, 100);
+
+      }
     }, function errorCallback(errorResponse) {
       $scope.loginParams.errorText = 'The username and password that you 
entered don\'t match.';
       $scope.SigningIn = false;
@@ -51,10 +62,25 @@ function LoginCtrl($scope, $rootScope, $http, 
$httpParamSerializer, baseUrlSrv)
     };
   };
 
+  //handle session logout message received from WebSocket
+  $rootScope.$on('session_logout', function(event, data) {
+    if ($rootScope.userName !== '') {
+      $rootScope.userName = '';
+      $rootScope.ticket = undefined;
+
+      setTimeout(function() {
+        $scope.loginParams = {};
+        $scope.loginParams.errorText = data.info;
+        angular.element('.nav-login-btn').click();
+      }, 1000);
+      var locationPath = $location.path();
+      $location.path('/').search('ref', locationPath);
+    }
+  });
+
   /*
    ** $scope.$on functions below
    */
-
   $scope.$on('initLoginValues', function() {
     initValues();
   });

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/97dfb898/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js
----------------------------------------------------------------------
diff --git 
a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js 
b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js
index 821884b..9c6e585 100644
--- a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js
+++ b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js
@@ -150,6 +150,8 @@ function websocketEvents($rootScope, $websocket, $location, 
baseUrlSrv) {
           }
         }]
       });
+    } else if (op === 'SESSION_LOGOUT') {
+      $rootScope.$broadcast('session_logout', data);
     } else if (op === 'CONFIGURATIONS_INFO') {
       $rootScope.$broadcast('configurationsInfo', data);
     } else if (op === 'INTERPRETER_SETTINGS') {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/97dfb898/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
index d40afc2..3784f5e 100644
--- 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
+++ 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
@@ -167,6 +167,7 @@ public class Message {
     GET_INTERPRETER_SETTINGS,     // [c-s] get interpreter settings
     INTERPRETER_SETTINGS,         // [s-c] interpreter settings
     ERROR_INFO,                   // [s-c] error information to be sent
+    SESSION_LOGOUT,               // [s-c] error information to be sent
     WATCHER,                      // [s-c] Change websocket to watcher mode.
     PARAGRAPH_ADDED,              // [s-c] paragraph is added
     PARAGRAPH_REMOVED,            // [s-c] paragraph deleted

Reply via email to