Browse Source

AMBARI-9660 Modify flow for checking and authenticating admin principal to make it more robust (Add Services / Add Host). (ababiichuk)

aBabiichuk 10 years ago
parent
commit
960ee94a2c

+ 21 - 1
ambari-web/app/controllers/main/admin/kerberos.js

@@ -270,6 +270,26 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
     });
     configProperties.setEach('isEditable', false);
     return configProperties;
+  },
+
+  getKDCSessionState: function(callback) {
+    App.ajax.send({
+      name: 'kerberos.session.state',
+      sender: this,
+      data: {
+        callback: callback
+      },
+      success: 'checkState'
+    })
+  },
+
+  checkState: function(data, opt, params) {
+    var res = Em.get(data, 'Services.attributes.kdc_validation_result');
+    var message = Em.get(data, 'Services.attributes.kdc_validation_failure_details');
+    if (res.toUpperCase() === "OK") {
+      params.callback();
+    } else {
+      App.showInvalidKDCPopup(opt, App.format.kdcErrorMsg(message, false));
+    }
   }
-  
 });

+ 0 - 15
ambari-web/app/controllers/main/host/add_controller.js

@@ -409,20 +409,5 @@ App.AddHostController = App.WizardController.extend({
       error: 'installServicesErrorCallback'
     }).then(callback, errorCallback || callback);
     return true;
-  },
-
-  installServicesSuccessCallback: function(json) {
-    if (json) {
-      // on success callback start deploy for secure cluster after submited credentials
-      if (this.getDBProperty('KDCAuthRequired') == true) {
-        this.setDBProperty('KDCAuthRequired', false);
-        this._super(json);
-        App.router.get('wizardStep9Controller').navigateStep();
-      } else {
-        this._super(json);
-      }
-    } else {
-      console.log('ERROR: Error occurred in parsing JSON data');
-    }
   }
 });

+ 17 - 21
ambari-web/app/controllers/main/service/add_controller.js

@@ -140,7 +140,7 @@ App.AddServiceController = App.WizardController.extend(App.AddSecurityConfigs, {
           this.load('cluster');
           this.set('content.additionalClients', []);
           this.set('installClientQueueLength', 0);
-          this.set('installClietsQueue', App.ajaxQueue.create({}));
+          this.set('installClietsQueue', App.ajaxQueue.create({abortOnError: false}));
         }
       }
     ]
@@ -537,7 +537,6 @@ App.AddServiceController = App.WizardController.extend(App.AddSecurityConfigs, {
    * for <code>installServicesRequest<code>
    */
   installServicesComplete: function () {
-    this.setDBProperty('KDCAuthRequired', false);
     App.get('router.wizardStep8Controller').set('servicesInstalled', true);
     this.setInfoForStep9();
     this.saveClusterState('ADD_SERVICES_INSTALLING_3');
@@ -550,7 +549,6 @@ App.AddServiceController = App.WizardController.extend(App.AddSecurityConfigs, {
    */
   installServices: function () {
     var self = this;
-    this.setDBProperty('KDCAuthRequired', false);
     this.set('content.cluster.oldRequestsId', []);
     this.installAdditionalClients().done(function () {
       self.installSelectedServices();
@@ -598,10 +596,8 @@ App.AddServiceController = App.WizardController.extend(App.AddSecurityConfigs, {
               counter: k,
               deferred: dfd
             },
-            success: 'installClientComplete',
-            error: 'installClientComplete',
-            kdcFailHandler: 'kdcFailHandler',
-            kdcCancelHandler: 'installSelectedServices'
+            success: 'installClientSuccess',
+            error: 'installClientError'
           });
         }
       }, this);
@@ -620,29 +616,29 @@ App.AddServiceController = App.WizardController.extend(App.AddSecurityConfigs, {
 
   /**
    * callback for when install clients success
-   * of fail with not KDC error
    * @param data
-   * @param params
    * @param opt
+   * @param params
    * @method installClientComplete
    */
-  installClientComplete: function(data, params, opt) {
-    if (this.getDBProperty('KDCAuthRequired')) {
-      this.setDBProperty('KDCAuthRequired', false);
-      this.installServices();
-      opt.deferred.reject();
-    } else if (this.get('installClientQueueLength') - 1 == opt.counter) {
-      opt.deferred.resolve();
+  installClientSuccess: function(data, opt, params) {
+    if (this.get('installClientQueueLength') - 1 == params.counter) {
+      params.deferred.resolve();
     }
   },
 
   /**
-   * kdc fail handler for installClients method
-   * @method kdcFailHandler
+   * callback for when install clients fail
+   * @param request
+   * @param ajaxOptions
+   * @param error
+   * @param opt
+   * @param params
    */
-  kdcFailHandler: function() {
-    this.setDBProperty('KDCAuthRequired', true);
-    this.saveClusterState('ADD_SERVICE_KDC_AUTHORIZATION');
+  installClientError: function(request, ajaxOptions, error, opt, params) {
+    if (this.get('installClientQueueLength') - 1 == params.counter) {
+      params.deferred.resolve();
+    }
   },
 
   checkSecurityStatus: function() {

+ 8 - 3
ambari-web/app/controllers/wizard/step8_controller.js

@@ -839,11 +839,16 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
   /**
    * Onclick handler for <code>next</code> button
    * @method submit
-   * @return {App.ModalPopup|null}
+   * @return {void}
    */
   submit: function () {
-    if (this.get('isSubmitDisabled')) return null;
-    return this.submitProceed();
+    if (!this.get('isSubmitDisabled')) {
+      if (this.get('content.controllerName') != 'installerController' && this.get('securityEnabled')) {
+        App.get('router.mainAdminKerberosController').getKDCSessionState(this.submitProceed.bind(this));
+      } else {
+        this.submitProceed();
+      }
+    }
   },
   /**
    * Update configurations for installed services.

+ 0 - 4
ambari-web/app/controllers/wizard/step9_controller.js

@@ -264,10 +264,6 @@ App.WizardStep9Controller = Em.Controller.extend({
       this.set('content.cluster.isCompleted', false);
       this.set('content.cluster.requestId', 1);
     }
-    // wait for valid credentials in secure mode if session was expired or entered credentials are invalid
-    if (this.get('wizardController').getDBProperty('KDCAuthRequired') == true && App.router.get('mainAdminKerberosController.securityEnabled')) {
-      return;
-    }
     var needPolling = false;
     var clusterStatus = this.get('content.cluster.status');
     console.log('navigateStep: clusterStatus = ' + clusterStatus);

+ 7 - 53
ambari-web/app/routes/add_host_routes.js

@@ -254,39 +254,13 @@ module.exports = App.WizardRoute.extend({
       var addHostController = router.get('addHostController');
       var wizardStep8Controller = router.get('wizardStep8Controller');
       addHostController.applyConfigGroup();
-      var successCallback = function () {
-        // In secure mode this callback will be called in case when user enter valid credentials if session was
-        // expired. 
-        // In other case just proceed to the next step.
-        if (App.router.get('mainAdminKerberosController.securityEnabled') && addHostController.getDBProperty('KDCAuthRequired') == true) {
-          // user has entered valid KDC credentials. Drop db property.
-          addHostController.setDBProperty('KDCAuthRequired', false);
-          // save current cluster status
-          addHostController.saveClusterState('ADD_HOSTS_INSTALLING_3');
-          // continue installation
-          App.router.get('wizardStep9Controller').navigateStep();
-        } else {
-          // We need to do recovery based on whether we are in Add Host or Installer wizard
-          addHostController.setInfoForStep9();
-          addHostController.saveClusterState('ADD_HOSTS_INSTALLING_3');
-          wizardStep8Controller.set('servicesInstalled', true);
-          router.transitionTo('step6');
-        }
-      };
-      var errorCallback = function(request) {
-        var KDCErrorMsg = App.ajax.getKDCErrorMgs(request);
-        // check if KDC credentials was expired and navigate user to next step.
-        // in this case install process is stopped until user enter valid KDC credentials.
-        if (!Em.isNone(KDCErrorMsg)) {
-          wizardStep8Controller.set('servicesInstalled', true);
-          router.transitionTo('step6');
-          addHostController.setDBProperty('KDCAuthRequired', true);
-          addHostController.saveClusterState('ADD_HOSTS_KDC_AUTHORIZATION');
-        } else {
-          successCallback();
-        }
-      };
-      addHostController.installServices(false, successCallback, errorCallback);
+      addHostController.installServices(false, function () {
+        addHostController.setInfoForStep9();
+        // We need to do recovery based on whether we are in Add Host or Installer wizard
+        addHostController.saveClusterState('ADD_HOSTS_INSTALLING_3');
+        wizardStep8Controller.set('servicesInstalled', true);
+        router.transitionTo('step6');
+      });
     }
   }),
 
@@ -304,26 +278,6 @@ module.exports = App.WizardRoute.extend({
           controller.setLowerStepsDisable(6);
         }
         controller.connectOutlet('wizardStep9', controller.get('content'));
-        // handle page refresh for enabled security. After page refresh `servicesInstalled` property will be set with default value
-        // On transition from step5 to step6 this code will not execute.
-        if (!App.router.get('wizardStep8Controller.servicesInstalled') && controller.getDBProperty('KDCAuthRequired') == true) {
-          // user refreshed the page. Try to install components
-          controller.installServices(false, function() {
-            // authorization successful
-            controller.setDBProperty('KDCAuthRequired', false);
-            // continue installation
-            wizardStep9Controller.navigateStep();
-            // save cluster state
-            controller.saveClusterState('ADD_HOSTS_INSTALLING_3');
-          }, function(request) {
-            var KDCErrorMsg = App.ajax.getKDCErrorMgs(request);
-            // check if error caused by expired KDC session or invalid credentials
-            if (!Em.isNone(KDCErrorMsg)) {
-              controller.setDBProperty('KDCAuthRequired', true);
-              controller.saveClusterState('ADD_HOSTS_KDC_AUTHORIZATION');
-            }
-          });
-        }
       });
     },
     back: Em.Router.transitionTo('step5'),

+ 7 - 17
ambari-web/app/utils/ajax/ajax.js

@@ -1258,6 +1258,12 @@ var urls = {
       };
     }
   },
+
+  'kerberos.session.state': {
+    'real': '/clusters/{clusterName}/services/KERBEROS?fields=Services/attributes/kdc_validation_result,Services/attributes/kdc_validation_failure_details',
+    'mock': ''
+  },
+
   'admin.kerberize.cluster': {
     'type': 'PUT',
     'real': '/clusters/{clusterName}',
@@ -2306,16 +2312,6 @@ var formatRequest = function (data) {
   return opt;
 };
 
-/**
- * Error messages for KDC administrator credentials error
- * is used for checking if error message is caused by bad KDC credentials
- * @type {{missingKDC: string, invalidKDC: string}}
- */
-var specialMsg = {
-  "missingKDC": "Missing KDC administrator credentials.",
-  "invalidKDC": "Invalid KDC administrator credentials.",
-  "missingRDCForRealm": "Failed to find a KDC for the specified realm - kadmin"
-};
 /**
  * Wrapper for all ajax requests
  *
@@ -2459,14 +2455,8 @@ var ajax = Em.Object.extend({
       var message = $.parseJSON(jqXHR.responseText).message;
     } catch (err) {}
     if (jqXHR.status === 400 && message) {
-      for(var m in specialMsg) {
-        if (specialMsg.hasOwnProperty(m) && message.contains(specialMsg[m]))
-          return m;
-      }
-    } else {
-      return null;
+      return App.format.kdcErrorMsg(message, true);
     }
-
   },
 
   /**

+ 26 - 0
ambari-web/app/utils/helper.js

@@ -513,6 +513,32 @@ App.format = {
    */
   taskStatus:function (_taskStatus) {
     return _taskStatus.toLowerCase();
+  },
+
+  /**
+   * simplify kdc error msg
+   * @param {string} message
+   * @param {boolean} strict if this flag is true ignore not defined msgs return null
+   *  else return input msg as is;
+   * @returns {*}
+   */
+  kdcErrorMsg: function(message, strict) {
+    /**
+     * Error messages for KDC administrator credentials error
+     * is used for checking if error message is caused by bad KDC credentials
+     * @type {{missingKDC: string, invalidKDC: string}}
+     */
+    var specialMsg = {
+      "missingKDC": "Missing KDC administrator credentials.",
+      "invalidKDC": "Invalid KDC administrator credentials.",
+      "missingRDCForRealm": "Failed to find a KDC for the specified realm - kadmin"
+    };
+
+    for (var m in specialMsg) {
+      if (specialMsg.hasOwnProperty(m) && message.contains(specialMsg[m]))
+        return specialMsg[m];
+    }
+    return strict ? null : message;
   }
 };
 

+ 10 - 13
ambari-web/test/controllers/wizard/step8_test.js

@@ -742,41 +742,38 @@ describe('App.WizardStep8Controller', function () {
   describe('#submit', function() {
     beforeEach(function() {
       sinon.stub(installerStep8Controller, 'submitProceed', Em.K);
-      sinon.spy(App, 'showConfirmationPopup');
+      sinon.stub(App.get('router.mainAdminKerberosController'), 'getKDCSessionState', Em.K);
     });
     afterEach(function() {
       installerStep8Controller.submitProceed.restore();
-      App.showConfirmationPopup.restore();
+      App.get('router.mainAdminKerberosController').getKDCSessionState.restore();
     });
     Em.A([
         {
           controllerName: 'addServiceController',
-          securityEnabled: true,
-          e: false
+          securityEnabled: true
         },
         {
           controllerName: 'addServiceController',
-          securityEnabled: false,
-          e: false
+          securityEnabled: false
         }
       ]).forEach(function (test) {
         it(test.controllerName + ' ' + test.securityEnabled.toString(), function () {
           installerStep8Controller.reopen({isSubmitDisabled: false, securityEnabled: test.securityEnabled, content: {controllerName: test.controllerName}});
           installerStep8Controller.submit();
-          if (test.e) {
-            expect(App.showConfirmationPopup.calledOnce).to.equal(true);
+          if (test.securityEnabled) {
+            expect(App.get('router.mainAdminKerberosController').getKDCSessionState.called).to.equal(true);
             expect(installerStep8Controller.submitProceed.called).to.equal(false);
-          }
-          else {
-            expect(App.showConfirmationPopup.called).to.equal(false);
-            expect(installerStep8Controller.submitProceed.calledOnce).to.equal(true);
+          } else {
+            expect(App.get('router.mainAdminKerberosController').getKDCSessionState.called).to.equal(false);
+            expect(installerStep8Controller.submitProceed.called).to.equal(true);
           }
         });
       });
     it('shouldn\'t do nothing if isSubmitDisabled is true', function() {
       installerStep8Controller.reopen({isSubmitDisabled: true});
       installerStep8Controller.submit();
-      expect(App.showConfirmationPopup.called).to.equal(false);
+      expect(App.get('router.mainAdminKerberosController').getKDCSessionState.called).to.equal(false);
       expect(installerStep8Controller.submitProceed.called).to.equal(false);
     });
   });

+ 33 - 0
ambari-web/test/utils/helper_test.js

@@ -289,6 +289,39 @@ describe('utils/helper', function() {
           })(inputName)
         }
       });
+      describe('#kdcErrorMsg()', function() {
+        var tests = [
+          {
+            r: "1 Missing KDC administrator credentials. and some text",
+            f: "Missing KDC administrator credentials."
+          },
+          {
+            r: "2 Invalid KDC administrator credentials. and some text",
+            f: "Invalid KDC administrator credentials."
+          },
+          {
+            r: "3 Failed to find a KDC for the specified realm - kadmin and some text",
+            f: "Failed to find a KDC for the specified realm - kadmin"
+          },
+          {
+            r: "4 some text",
+            f: null,
+            s: true
+          },
+          {
+            r: "4 some text",
+            f: "4 some text",
+            s: false
+          }
+        ];
+
+        tests.forEach(function(t) {
+          it("kdcErrorMsg for " + t.f + " with strict " + t.s, function() {
+            expect(App.format.kdcErrorMsg(t.r, t.s)).to.be.equal(t.f);
+          })
+        });
+
+      })
     });
   });
   describe('#App.permit()', function() {