Jelajahi Sumber

AMBARI-16245. Cluster User should not have access to component logs (alexantonenko)

Alex Antonenko 9 tahun lalu
induk
melakukan
4540d4611b

+ 1 - 0
ambari-web/app/app.js

@@ -35,6 +35,7 @@ module.exports = Em.Application.create({
   }),
   isAdmin: false,
   isOperator: false,
+  isClusterUser: false,
   isPermissionDataLoaded: false,
   auth: null,
   isOnlyViewUser: function() {

+ 13 - 1
ambari-web/app/mappers/users_mapper.js

@@ -26,7 +26,8 @@ App.usersMapper = App.QuickDataMapper.create({
     admin: 'Users.admin',
     operator: 'Users.operator',
     permissions: 'permissions',
-    user_type: 'Users.user_type'
+    user_type: 'Users.user_type',
+    cluster_user: 'Users.cluster_user'
   },
   map: function (json) {
     var self = this;
@@ -40,6 +41,7 @@ App.usersMapper = App.QuickDataMapper.create({
         }
         item.Users.admin = self.isAdmin(item.permissions);
         item.Users.operator = self.isOperator(item.permissions);
+        item.Users.cluster_user = self.isClusterUser(item.permissions);
         result.push(self.parseIt(item, self.config));
         App.store.loadMany(self.get('model'), result);
       }
@@ -63,5 +65,15 @@ App.usersMapper = App.QuickDataMapper.create({
    **/
   isOperator: function(permissionList) {
     return permissionList.indexOf('CLUSTER.ADMINISTRATOR') > -1 && !(permissionList.indexOf('AMBARI.ADMINISTRATOR') > -1);
+  },
+
+  /**
+   * Determines that user has only one permission CLUSTER.USER.
+   *
+   * @param {String[]} permissionList
+   * @return {Boolean}
+   */
+  isClusterUser: function(permissionList) {
+    return permissionList.length === 1 && permissionList[0] === 'CLUSTER.USER';
   }
 });

+ 2 - 0
ambari-web/app/models/user.js

@@ -26,6 +26,8 @@ App.User = DS.Model.extend({
   auditItems:DS.hasMany('App.ServiceAudit'),
   admin: DS.attr('boolean'),
   operator: DS.attr('boolean'),
+  clusterUser: DS.attr('boolean'),
+
   /**
    * List of permissions assigned to user
    *  Available permissions:

+ 6 - 1
ambari-web/app/router.js

@@ -462,7 +462,8 @@ App.Router = Em.Router.extend({
       if (clusterPermissions.contains('CLUSTER.ADMINISTRATOR')) {
         App.setProperties({
           isAdmin: true,
-          isOperator: true
+          isOperator: true,
+          isClusterUser: false
         });
       }
       if (App.get('isOnlyViewUser')) {
@@ -583,6 +584,7 @@ App.Router = Em.Router.extend({
       isAdmin: false,
       auth: null,
       isOperator: false,
+      isClusterUser: false,
       isPermissionDataLoaded: false
     });
     this.set('loggedIn', false);
@@ -677,6 +679,9 @@ App.Router = Em.Router.extend({
         if (user.operator) {
           App.set('isOperator', true);
         }
+        if (user.cluster_user) {
+          App.set('isClusterUser', true);
+        }
         App.set('isPermissionDataLoaded', true);
       }
     }

+ 14 - 12
ambari-web/app/templates/application.hbs

@@ -26,18 +26,20 @@
                                                                            title="Apache Ambari"></a>
             <a class="brand" {{translateAttr href="topnav.logo.href"}} title="Apache Ambari">{{t app.name}}</a>
             <a class="brand cluster-name" href="javascript:void(null);" {{bindAttr title="clusterName"}}>
-              <span {{action "showPopup" target="App.router.backgroundOperationsController"}} >{{clusterDisplayName}} </span>
-              {{#with App.router.backgroundOperationsController}}
-                {{#if allOperationsCount}}
-                  <i class="icon-caret-left ops-count"></i><span id="span-bg-operation-count"
-                                                                 class="label operations-count" {{action "showPopup" target="App.router.backgroundOperationsController"}}>
-                    {{allOperationsCount}} {{pluralize allOperationsCount singular="t:op" plural="t:ops"}}</span>
-                {{else}}
-                  <i class="icon-caret-left"></i><span id="span-bg-operation-count"
-                                                       class="label" {{action "showPopup" target="App.router.backgroundOperationsController"}}>
-                    {{allOperationsCount}} {{pluralize allOperationsCount singular="t:op" plural="t:ops"}}</span>
-                {{/if}}
-              {{/with}}
+              {{#unless App.isClusterUser}}
+                <span {{action "showPopup" target="App.router.backgroundOperationsController"}} >{{clusterDisplayName}} </span>
+                {{#with App.router.backgroundOperationsController}}
+                  {{#if allOperationsCount}}
+                    <i class="icon-caret-left ops-count"></i><span id="span-bg-operation-count"
+                                                                   class="label operations-count" {{action "showPopup" target="App.router.backgroundOperationsController"}}>
+                      {{allOperationsCount}} {{pluralize allOperationsCount singular="t:op" plural="t:ops"}}</span>
+                  {{else}}
+                    <i class="icon-caret-left"></i><span id="span-bg-operation-count"
+                                                         class="label" {{action "showPopup" target="App.router.backgroundOperationsController"}}>
+                      {{allOperationsCount}} {{pluralize allOperationsCount singular="t:op" plural="t:ops"}}</span>
+                  {{/if}}
+                {{/with}}
+              {{/unless}}
             {{#if App.router.clusterController.isAlertsLoaded}}
               {{#if App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}}
                 <span {{bindAttr class=":label App.router.mainAlertDefinitionsController.isCriticalAlerts:alert-crit-count:alert-warn-count"}} {{action "showPopup" target="App.router.mainAlertInstancesController"}}>

+ 5 - 0
ambari-web/app/utils/host_progress_popup.js

@@ -291,6 +291,7 @@ App.HostPopup = Em.Object.create({
    * @method initPopup
    */
   initPopup: function (serviceName, controller, isBackgroundOperations, requestId) {
+    if (App.get('isClusterUser')) return;
     if (!isBackgroundOperations) {
       this.clearHostPopup();
       this.set("popupHeaderName", serviceName);
@@ -822,6 +823,10 @@ App.HostPopup = Em.Object.create({
        */
       detailedProperties: self.get('detailedProperties'),
 
+      isVisible: function() {
+        return !(App.get('isClusterUser') && isBackgroundOperations);
+      }.property('App.isClusterUser'),
+
       didInsertElement: function () {
         this._super();
         this.set('isOpen', true);

+ 2 - 0
ambari-web/app/views/common/log_tail_view.js

@@ -40,6 +40,8 @@ App.LogTailView = Em.View.extend(App.InfiniteScrollMixin, {
 
   content: null,
 
+  isVisible: Em.computed.not('App.isClusterUser'),
+
   /**
    * elements size are:
    * .modal margin 40px x 2

+ 1 - 0
ambari-web/app/views/main/host/logs_view.js

@@ -25,6 +25,7 @@ var fileUtils = require('utils/file_utils');
 App.MainHostLogsView = App.TableView.extend({
   templateName: require('templates/main/host/logs'),
 
+  isVisible: Em.computed.not('App.isClusterUser'),
   classNames: ['logs-tab-content'],
 
   /**

+ 1 - 1
ambari-web/app/views/main/host/menu.js

@@ -58,7 +58,7 @@ App.MainHostMenuView = Em.CollectionView.extend({
         routing: 'logs',
         hidden: function () {
           if (App.get('supports.logSearch')) {
-            return !App.Service.find().someProperty('serviceName', 'LOGSEARCH');
+            return !(App.Service.find().someProperty('serviceName', 'LOGSEARCH') && !App.get('isClusterUser'));
           }
           return true;
         }.property('App.supports.logSearch'),

+ 11 - 0
ambari-web/test/mappers/users_mapper_test.js

@@ -37,4 +37,15 @@ describe('App.usersMapper', function () {
     });
   });
 
+  describe('#isClusterUser', function() {
+    var tests = [
+      {i:["AMBARI.ADMINISTRATOR", "CLUSTER.USER"],e:false,m:'is cluster user'},
+      {i:["CLUSTER.USER"],e:true,m:'has admin role'}
+    ];
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        expect(App.usersMapper.isClusterUser(test.i)).to.equal(test.e);
+      });
+    });
+  });
 });

+ 12 - 0
ambari-web/test/views/main/host/menu_test.js

@@ -30,6 +30,7 @@ describe('App.MainHostMenuView', function () {
     beforeEach(function () {
       this.mock = sinon.stub(App, 'get');
       this.serviceMock = sinon.stub(App.Service, 'find');
+      this.clusterUserMock = this.mock.withArgs('isClusterUser');
     });
 
     afterEach(function () {
@@ -60,25 +61,36 @@ describe('App.MainHostMenuView', function () {
       {
         logSearch: false,
         services: [{serviceName: 'LOGSEARCH'}],
+        isClusterUser: false,
         m: '`logs` tab is invisible',
         e: true
       },
       {
         logSearch: true,
         services: [],
+        isClusterUser: false,
         m: '`logs` tab is invisible because service not installed',
         e: true
       },
       {
         logSearch: true,
         services: [{serviceName: 'LOGSEARCH'}],
+        isClusterUser: false,
         m: '`logs` tab is visible',
         e: false
+      },
+      {
+        logSearch: true,
+        services: [{serviceName: 'LOGSEARCH'}],
+        isClusterUser: true,
+        m: '`logs` tab is hidden because user has no access',
+        e: true
       }
     ]).forEach(function(test) {
       it(test.m, function() {
         this.mock.withArgs('supports.logSearch').returns(test.logSearch);
         this.serviceMock.returns(test.services);
+        this.clusterUserMock.returns(test.isClusterUser);
         view.propertyDidChange('content');
         expect(view.get('content').findProperty('name', 'logs').get('hidden')).to.equal(test.e);
       });