瀏覽代碼

AMBARI-13819. Ambari needs to support an explicit login URL for local users

Alex Antonenko 9 年之前
父節點
當前提交
65629e789e
共有 2 個文件被更改,包括 95 次插入3 次删除
  1. 34 3
      ambari-web/app/router.js
  2. 61 0
      ambari-web/test/router_test.js

+ 34 - 3
ambari-web/app/router.js

@@ -56,6 +56,7 @@ App.Router = Em.Router.extend({
   backBtnForHigherStep: false,
   transitionInProgress: false,
 
+  localUserAuthUrl: '/login/local',
 
   /**
    * Is true, if cluster.provisioning_state is equal to 'INSTALLED'
@@ -112,7 +113,6 @@ App.Router = Em.Router.extend({
    * @param wizardType one of <code>installer</code>, <code>addHost</code>, <code>addServices</code>
    */
   getWizardCurrentStep: function (wizardType) {
-    var loginName = this.getLoginName();
     var currentStep = App.db.getWizardCurrentStep(wizardType);
     if (!currentStep) {
       currentStep = wizardType === 'installer' ? '0' : '1';
@@ -186,9 +186,24 @@ App.Router = Em.Router.extend({
     }
   },
 
+  /**
+
+   * If authentication failed, need to check for jwt auth url
+   * and redirect user if current location is not <code>localUserAuthUrl</code>
+   *
+   * @param {?object} data
+   */
   onAuthenticationError: function (data) {
     if (data.status === 403) {
-      this.setAuthenticated(false);
+      try {
+        var responseJson = JSON.parse(data.responseText);
+        if (responseJson.jwtProviderUrl && this.get('location.lastSetURL') !== this.get('localUserAuthUrl')) {
+          this.redirectByURL(responseJson.jwtProviderUrl + encodeURIComponent(this.getCurrentLocationUrl()));
+        }
+      } catch (e) {
+      } finally {
+        this.setAuthenticated(false);
+      }
     }
   },
 
@@ -549,6 +564,14 @@ App.Router = Em.Router.extend({
     }
   },
 
+  redirectByURL: function(url) {
+    window.location.href = url;
+  },
+
+  getCurrentLocationUrl: function() {
+    return window.location.href;
+  },
+
   root: Em.Route.extend({
     index: Em.Route.extend({
       route: '/',
@@ -560,7 +583,7 @@ App.Router = Em.Router.extend({
     },
 
     login: Em.Route.extend({
-      route: '/login',
+      route: '/login:suffix',
 
       /**
        *  If the user is already logged in, redirect to where the user was previously
@@ -584,6 +607,14 @@ App.Router = Em.Router.extend({
       connectOutlets: function (router, context) {
         $('title').text(Em.I18n.t('app.name'));
         router.get('applicationController').connectOutlet('login');
+      },
+
+      serialize: function(router, context) {
+        // check for login/local hash
+        var location = router.get('location.location.hash');
+        return {
+          suffix: location === '#' + router.get('localUserAuthUrl') ? '/local' : ''
+        };
       }
     }),
 

+ 61 - 0
ambari-web/test/router_test.js

@@ -446,4 +446,65 @@ describe('App.Router', function () {
       expect(router.transitionToViews.calledOnce).to.be.true;
     });
   });
+
+  describe("#getAuthenticated", function() {
+    [
+      {
+        lastSetURL: '/login/local',
+        isResolved: false,
+        responseData: {
+          responseText: "",
+          status: 403
+        },
+        redirectCalled: false,
+        m: 'no jwtProviderUrl in auth response, no redirect'
+      },
+      {
+        lastSetURL: '/main/dashboard',
+        isResolved: false,
+        responseData: {
+          responseText: JSON.stringify({ jwtProviderUrl: 'http://some.com?originalUrl=' }),
+          status: 403
+        },
+        redirectCalled: true,
+        m: 'jwtProviderUrl is present, current location not local login url, redirect according to jwtProviderUrl value'
+      },
+      {
+        lastSetURL: '/login/local',
+        isResolved: false,
+        responseData: {
+          responseText: JSON.stringify({ jwtProviderUrl: 'http://some.com?originalUrl=' }),
+          status: 403
+        },
+        redirectCalled: false,
+        m: 'jwtProviderUrl is present, current location is local login url, no redirect'
+      }
+    ].forEach(function(test) {
+      it(test.m, function() {
+        var router = App.Router.create();
+        var mockCurrentUrl = 'http://localhost:3333/#/some/hash';
+        router.set('location.lastSetURL', test.lastSetURL);
+        sinon.stub(App.ajax, 'send', function() {
+          if (!test.isResolved) {
+            router.onAuthenticationError(test.responseData);
+          }
+          return {
+            complete: function() {}
+          };
+        });
+        sinon.stub(router, 'getCurrentLocationUrl').returns(mockCurrentUrl);
+        sinon.stub(router, 'redirectByURL', Em.K);
+        router.getAuthenticated();
+        expect(router.redirectByURL.calledOnce).to.be.eql(test.redirectCalled);
+        if (test.redirectCalled) {
+          expect(router.redirectByURL.args[0][0]).to.be.eql(JSON.parse(test.responseData.responseText).jwtProviderUrl + encodeURIComponent(mockCurrentUrl));
+        }
+        App.ajax.send.restore();
+        router.getCurrentLocationUrl.restore();
+        router.redirectByURL.restore();
+      });
+    });
+
+  });
+
 });