[ISSUE #70] The rocketmq-dashboard supports ACL configuration (#71)

* Add Acl menu, support config acl.

* Optimize one line code.

* Add some unit tests for acl.

* Add permission control by role and optimize some code.

* The secret keys are hidden by asterisks.

* Search acl data will exclude secretKey info if the login role is not admin in the background.

* Optimize some code again.

* recover default application.yml config
This commit is contained in:
Xiaodong Xu
2022-03-05 10:34:39 +08:00
committed by GitHub
parent 0fc7ca904d
commit 4269879d93
17 changed files with 2065 additions and 13 deletions

View File

@@ -113,5 +113,6 @@
<script type="text/javascript" src="src/remoteApi/remoteApi.js"></script>
<script type="text/javascript" src="vendor/preLoading/main.js"></script>
<script type="text/javascript" src="src/login.js"></script>
<script type="text/javascript" src="src/acl.js"></script>
</body>
</html>

View File

@@ -0,0 +1,540 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var module = app;
module.controller('aclController', ['$scope', 'ngDialog', '$http', 'Notification', '$window', function ($scope, ngDialog, $http, Notification, $window) {
$scope.paginationConf = {
currentPage: 1,
totalItems: 0,
itemsPerPage: 10,
pagesLength: 15,
perPageOptions: [10],
rememberPerPage: 'perPageItems',
onChange: function () {
$scope.showPlainAccessConfigs(this.currentPage, this.totalItems);
}
};
$scope.plainAccessConfigs = [];
$scope.allPlainAccessConfigs = [];
$scope.globalWhiteAddrs = [];
$scope.allGlobalWhiteAddrs = [];
$scope.userRole = $window.sessionStorage.getItem("userrole");
$scope.writeOperationEnabled = $scope.userRole == null ? true : ($scope.userRole == 1 ? true : false);
$scope.showSecretKeyType = {};
$scope.refreshPlainAccessConfigs = function () {
$http({
method: "GET",
url: "acl/config.query",
params: {}
}).success(function (resp) {
// globalWhiteAddrs
// plainAccessConfigs
if (resp.status == 0) {
$scope.allPlainAccessConfigs = resp.data.plainAccessConfigs;
$scope.allGlobalWhiteAddrs = resp.data.globalWhiteAddrs;
$scope.showSecretKeyType = {};
$scope.allPlainAccessConfigs.forEach(e => $scope.showSecretKeyType[e.accessKey] = {
type: 'password',
action: 'SHOW'
});
$scope.showPlainAccessConfigs(1, $scope.allPlainAccessConfigs.length);
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
$scope.refreshPlainAccessConfigs();
$scope.filterStr = "";
$scope.$watch('filterStr', function () {
$scope.paginationConf.currentPage = 1;
$scope.filterList(1);
});
$scope.filterList = function (currentPage) {
var lowExceptStr = $scope.filterStr.toLowerCase();
var canShowList = [];
$scope.allPlainAccessConfigs.forEach(function (element) {
if (element.accessKey.toLowerCase().indexOf(lowExceptStr) != -1) {
canShowList.push(element);
}
});
$scope.paginationConf.totalItems = canShowList.length;
var perPage = $scope.paginationConf.itemsPerPage;
var from = (currentPage - 1) * perPage;
var to = (from + perPage) > canShowList.length ? canShowList.length : from + perPage;
$scope.plainAccessConfigs = canShowList.slice(from, to);
};
$scope.showPlainAccessConfigs = function (currentPage, totalItem) {
var perPage = $scope.paginationConf.itemsPerPage;
var from = (currentPage - 1) * perPage;
var to = (from + perPage) > totalItem ? totalItem : from + perPage;
$scope.plainAccessConfigs = $scope.allPlainAccessConfigs.slice(from, to);
$scope.paginationConf.totalItems = totalItem;
$scope.filterList($scope.paginationConf.currentPage)
};
// add acl account
$scope.openAddDialog = function () {
var request = {};
request.accessKey = '';
request.secretKey = '';
request.admin = false;
request.defaultTopicPerm = 'DENY';
request.defaultGroupPerm = 'SUB';
ngDialog.open({
preCloseCallback: function (value) {
$scope.refreshPlainAccessConfigs();
},
template: 'addAclAccountDialog',
controller: 'addAclAccountDialogController',
data: request
});
}
$scope.deleteAclConfig = function (accessKey) {
$http({
method: "POST",
url: "acl/delete.do",
data: {accessKey: accessKey}
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
$scope.refreshPlainAccessConfigs();
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
$scope.openUpdateDialog = function (request) {
ngDialog.open({
preCloseCallback: function (value) {
$scope.refreshPlainAccessConfigs();
},
template: 'updateAclAccountDialog',
controller: 'updateAclAccountDialogController',
data: request
});
}
// add acl topic permission
$scope.openAddTopicDialog = function (request) {
$.extend(request, {pub: true, sub: true, deny: false})
ngDialog.open({
preCloseCallback: function (value) {
$scope.refreshPlainAccessConfigs();
},
template: 'addAclTopicDialog',
controller: 'addAclTopicDialogController',
data: request
});
}
// update acl topic permission
$scope.openUpdateTopicDialog = function (request, topic) {
var perm = {pub: false, sub: false, deny: false};
var topicInfo = topic.split('=');
$.each(topicInfo[1].split('|'), function (i, e) {
switch (e) {
case 'PUB':
perm.pub = true;
break;
case 'SUB':
perm.sub = true;
break;
case 'DENY':
perm.deny = true;
break;
default:
break;
}
});
$.extend(request, perm, {topic: topicInfo[0]});
ngDialog.open({
preCloseCallback: function (value) {
$scope.refreshPlainAccessConfigs();
},
template: 'updateAclTopicDialog',
controller: 'updateAclTopicDialogController',
data: request
});
}
// add acl group permission
$scope.openAddGroupDialog = function (request) {
$.extend(request, {pub: true, sub: true, deny: false})
ngDialog.open({
preCloseCallback: function (value) {
$scope.refreshPlainAccessConfigs();
},
template: 'addAclGroupDialog',
controller: 'addAclGroupDialogController',
data: request
});
}
// update acl group permission
$scope.openUpdateGroupDialog = function (request, group) {
var perm = {pub: false, sub: false, deny: false};
var groupInfo = group.split('=');
$.each(groupInfo[1].split('|'), function (i, e) {
switch (e) {
case 'PUB':
perm.pub = true;
break;
case 'SUB':
perm.sub = true;
break;
case 'DENY':
perm.deny = true;
break;
default:
break;
}
});
$.extend(request, perm, {group: groupInfo[0]});
ngDialog.open({
preCloseCallback: function (value) {
$scope.refreshPlainAccessConfigs();
},
template: 'updateAclGroupDialog',
controller: 'updateAclGroupDialogController',
data: request
});
}
$scope.deletePermConfig = function (config, name, type) {
var request = {config: config};
switch (type) {
case 'topic':
request.topicPerm = name;
break;
case 'group':
request.groupPerm = name;
break;
default:
break;
}
$http({
method: "POST",
url: "acl/perm/delete.do",
data: request
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
$scope.refreshPlainAccessConfigs();
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
$scope.synchronizeData = function (request) {
$http({
method: "POST",
url: "acl/sync.do",
data: request
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
$scope.refreshPlainAccessConfigs();
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
$scope.openAddAddrDialog = function () {
ngDialog.open({
preCloseCallback: function (value) {
$scope.refreshPlainAccessConfigs();
},
template: 'addWhiteListDialog',
controller: 'addWhiteListDialogController'
});
}
$scope.deleteGlobalWhiteAddr = function (request) {
$http({
method: "DELETE",
url: "acl/white/list/delete.do?request=" + request
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
$scope.refreshPlainAccessConfigs();
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
$scope.synchronizeWhiteList = function (request) {
$http({
method: "POST",
url: "acl/white/list/sync.do",
data: request
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
$scope.refreshPlainAccessConfigs();
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
$scope.switchSecretKeyType = function (accessKey) {
if ($scope.showSecretKeyType[accessKey].type == 'password') {
$scope.showSecretKeyType[accessKey] = {type: 'text', action: 'HIDE'};
} else {
$scope.showSecretKeyType[accessKey] = {type: 'password', action: 'SHOW'};
}
}
}]);
module.controller('addAclAccountDialogController', ['$scope', 'ngDialog', '$http', 'Notification', function ($scope, ngDialog, $http, Notification) {
$scope.addRequest = function (requestItem) {
$http({
method: "POST",
url: "acl/add.do",
data: requestItem
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
}]
);
module.controller('updateAclAccountDialogController', ['$scope', 'ngDialog', '$http', 'Notification', function ($scope, ngDialog, $http, Notification) {
$scope.updateAclAccountRequest = function (requestItem) {
$http({
method: "POST",
url: "acl/update.do",
data: requestItem
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
}]
);
module.controller('addAclTopicDialogController', ['$scope', 'ngDialog', '$http', 'Notification', function ($scope, ngDialog, $http, Notification) {
$scope.updateAclAccountRequest = function (requestItem) {
if ((requestItem.deny && requestItem.sub) || (requestItem.deny && requestItem.pub)) {
alert("Forbid deny && pub/sub.");
return false;
}
if (!requestItem.topic) {
alert("topic is null");
return false;
}
//var request = requestItem.originalData;
var originalData = $.extend(true, {}, requestItem.originalData);
if (!originalData.topicPerms) {
originalData.topicPerms = new Array();
}
var topicPerm = concatPerm(requestItem.topic, requestItem.pub ? 0x01 : 0, requestItem.sub ? 0x02 : 0, requestItem.deny ? 0x04 : 0);
originalData.topicPerms.push(topicPerm);
var request = {topicPerm: topicPerm, config: originalData};
$http({
method: "POST",
url: "acl/topic/add.do",
data: request
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
}]
);
module.controller('updateAclTopicDialogController', ['$scope', 'ngDialog', '$http', 'Notification', function ($scope, ngDialog, $http, Notification) {
$scope.updateAclAccountRequest = function (requestItem) {
if ((requestItem.deny && requestItem.sub) || (requestItem.deny && requestItem.pub)) {
alert("Forbid deny && pub/sub.");
return false;
}
var originalData = $.extend(true, {}, requestItem.originalData);
if (!originalData.topicPerms) {
originalData.topicPerms = new Array();
}
var topicPerm = concatPerm(requestItem.topic, requestItem.pub ? 0x01 : 0, requestItem.sub ? 0x02 : 0, requestItem.deny ? 0x04 : 0);
for (var i = 0; i < originalData.topicPerms.length; i++) {
if (originalData.topicPerms[i].split('=')[0] == requestItem.topic) {
originalData.topicPerms[i] = topicPerm;
}
}
var request = {topicPerm: topicPerm, config: originalData};
$http({
method: "POST",
url: "acl/topic/add.do",
data: request
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
}]
);
module.controller('addAclGroupDialogController', ['$scope', 'ngDialog', '$http', 'Notification', function ($scope, ngDialog, $http, Notification) {
$scope.updateAclAccountRequest = function (requestItem) {
if ((requestItem.deny && requestItem.sub) || (requestItem.deny && requestItem.pub)) {
alert("Forbid deny && pub/sub.");
return false;
}
//var request = requestItem.originalData;
var originalData = $.extend(true, {}, requestItem.originalData);
if (!originalData.groupPerms) {
originalData.groupPerms = new Array();
}
var groupPerm = concatPerm(requestItem.group, requestItem.pub ? 0x01 : 0, requestItem.sub ? 0x02 : 0, requestItem.deny ? 0x04 : 0);
originalData.groupPerms.push(groupPerm);
var request = {groupPerm: groupPerm, config: originalData};
$http({
method: "POST",
url: "acl/group/add.do",
data: request
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
}]
);
module.controller('updateAclGroupDialogController', ['$scope', 'ngDialog', '$http', 'Notification', function ($scope, ngDialog, $http, Notification) {
$scope.updateAclAccountRequest = function (requestItem) {
if ((requestItem.deny && requestItem.sub) || (requestItem.deny && requestItem.pub)) {
alert("Forbid deny && pub/sub.");
return false;
}
var originalData = $.extend(true, {}, requestItem.originalData);
if (!originalData.groupPerms) {
originalData.groupPerms = new Array();
}
var groupPerm = concatPerm(requestItem.group, requestItem.pub ? 0x01 : 0, requestItem.sub ? 0x02 : 0, requestItem.deny ? 0x04 : 0);
for (var i = 0; i < originalData.groupPerms.length; i++) {
if (originalData.groupPerms[i].split('=')[0] == requestItem.group) {
originalData.groupPerms[i] = groupPerm;
}
}
var request = {groupPerm: groupPerm, config: originalData};
$http({
method: "POST",
url: "acl/group/add.do",
data: request
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
}]
);
/**
*
* pub: 0x01, sub: 0x02, deny: 0x04
*/
function concatPerm(name, pub, sub, deny) {
var perm = '';
switch (pub | sub | deny) {
case 0x01:
perm = 'PUB';
break;
case 0x02:
perm = 'SUB';
break;
case 0x03:
perm = 'PUB|SUB';
break;
case 0x04:
perm = 'DENY';
break;
default:
perm = 'DENY';
break;
}
return name + '=' + perm;
}
module.controller('addWhiteListDialogController', ['$scope', 'ngDialog', '$http', 'Notification', function ($scope, ngDialog, $http, Notification) {
$scope.addWhiteListRequest = function (requestItem) {
$http({
method: "POST",
url: "acl/white/list/add.do",
data: requestItem.split(',')
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
}]
);
module.controller('aclBelongItemDialogController', ['$scope', 'ngDialog', '$http', 'Notification', function ($scope, ngDialog, $http, Notification) {
$scope.postBelongItemRequest = function (topicRequestItem) {
topicRequestItem.type = 1
$http({
method: "POST",
url: "acl/belong/item/add.do",
data: topicRequestItem
}).success(function (resp) {
if (resp.status == 0) {
Notification.info({message: "success!", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
}
}]
);

View File

@@ -49,6 +49,15 @@ var app = angular.module('app', [
}
console.log('initFlag0='+ initFlag + ' loginFlag0==='+loginFlag);
$http({
method: "GET",
url: "acl/enable.query"
}).success(function (resp) {
if (resp && resp.status == 0) {
$rootScope.show = resp.data;
}
});
$rootScope.$on('$locationChangeStart', function (event, next, current) {
// redirect to login page if not logged in and trying to access a restricted page
init(function(resp){
@@ -204,6 +213,9 @@ app.config(['$routeProvider', '$httpProvider','$cookiesProvider','getDictNamePro
}).when('/ops', {
templateUrl: 'view/pages/ops.html',
controller:'opsController'
}).when('/acl', {
templateUrl: 'view/pages/acl.html',
controller: 'aclController'
}).when('/404', {
templateUrl: 'view/pages/404.html'
}).otherwise('/404');

View File

@@ -113,5 +113,15 @@ var en = {
"EXPORT": "export",
"NO_MATCH_RESULT": "no match result",
"BATCH_RESEND": "batchReSend",
"BATCH_EXPORT": "batchExport"
"BATCH_EXPORT": "batchExport",
"WHITE_LIST":"White List",
"ACCOUNT_INFO":"Account Info",
"IS_ADMIN":"Is Admin",
"DEFAULT_TOPIC_PERM":"Default Topic Permission",
"DEFAULT_GROUP_PERM":"Default Group Permission",
"TOPIC_PERM":"Topic Permission",
"GROUP_PERM":"Group Permission",
"SYNCHRONIZE":"Synchronize Data",
"SHOW":"Show",
"HIDE":"Hide"
}

View File

@@ -114,5 +114,15 @@ var zh = {
"EXPORT": "导出",
"NO_MATCH_RESULT": "没有查到符合条件的结果",
"BATCH_RESEND": "批量重发",
"BATCH_EXPORT": "批量导出"
"BATCH_EXPORT": "批量导出",
"WHITE_LIST":"白名单",
"ACCOUNT_INFO":"账户信息",
"IS_ADMIN":"是否管理员",
"DEFAULT_TOPIC_PERM":"topic默认权限",
"DEFAULT_GROUP_PERM":"消费组默认权限",
"TOPIC_PERM":"topic权限",
"GROUP_PERM":"消费组权限",
"SYNCHRONIZE":"同步",
"SHOW":"显示",
"HIDE":"隐藏"
}

View File

@@ -289,3 +289,15 @@
.table.text-middle>tbody>tr>td,.table.text-middle>tbody>tr>th{
vertical-align: middle;
}
.perm-table{width: 100%;}
.perm-table .perm-tg{width: 70%;}
.perm-table .center{border-left: 1px solid #e4dddd; border-right: 1px solid #e4dddd;}
.input-none {
border: 0;
outline: none;
background-color: rgba(0, 0, 0, 0);
cursor: text !important;
width: 60%;
}

View File

@@ -36,6 +36,7 @@
<li ng-class="path =='message' ? 'active':''"><a ng-href="#/message">{{'MESSAGE' | translate}}</a></li>
<li ng-class="path =='dlqMessage' ? 'active':''"><a ng-href="#/dlqMessage">{{'DLQ_MESSAGE' | translate}}</a></li>
<li ng-class="path =='messageTrace' ? 'active':''"><a ng-href="#/messageTrace">{{'MESSAGETRACE' | translate}}</a></li>
<li ng-show="{{ show }}" ng-class="path =='acl' ? 'active':''"><a ng-href="#/acl">Acl</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">

View File

@@ -0,0 +1,483 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<div class="container-fluid" id="deployHistoryList">
<div class="modal-body">
<div ng-cloak="" class="tabsdemoDynamicHeight">
<md-content>
<md-tabs md-dynamic-height="" md-border-bottom="">
<md-tab label="Account Info">
<md-content class="md-padding" style="min-height:600px">
<form class="form-inline pull-left col-sm-12">
<div class="form-group">
<label>Access Key:</label>
<input class="form-control" style="width: 450px" type="text" ng-model="filterStr"/>
</div>
<button ng-show="writeOperationEnabled" class="btn btn-raised btn-sm btn-primary"
type="button"
ng-click="openAddDialog()">{{'ADD' |
translate}}
</button>
</form>
<table class="table table-bordered">
<tr>
<th class="text-center">Access Key</th>
<th ng-show="writeOperationEnabled" class="text-center">Secret Key</th>
<th class="text-center">{{'IS_ADMIN' | translate}}</th>
<th class="text-center">{{'DEFAULT_TOPIC_PERM' | translate}}</th>
<th class="text-center">{{'DEFAULT_GROUP_PERM' | translate}}</th>
<th class="text-center">{{'TOPIC_PERM' | translate}}</th>
<th class="text-center">{{'GROUP_PERM' | translate}}</th>
<th ng-show="writeOperationEnabled" class="text-center">
{{'OPERATION' | translate}}
</th>
</tr>
<tr ng-repeat="item in plainAccessConfigs">
<td class="text-center">{{item.accessKey}}</td>
<td ng-show="writeOperationEnabled" class="text-center">
<input type="{{showSecretKeyType[item.accessKey].type}}"
value="{{item.secretKey}}" class="input-none" ng-disabled="true"/>
<a href="javascript:;"
ng-click="switchSecretKeyType(item.accessKey)">{{showSecretKeyType[item.accessKey].action | translate}}</a>
</td>
<td class="text-center">{{item.admin}}</td>
<td class="text-center">{{item.defaultTopicPerm}}</td>
<td class="text-center">{{item.defaultGroupPerm}}</td>
<td class="text-center">
<table ng-repeat="topic in item.topicPerms" class="perm-table">
<tr>
<td class="perm-tg">{{topic}}</td>
<td ng-show="writeOperationEnabled" class="center"><a
href="javascript:;"
ng-click="openUpdateTopicDialog(item, topic)">
{{'UPDATE' | translate}}</a></td>
<td ng-show="writeOperationEnabled"><a href="javascript:;"
ng-confirm-click="Are you sure to delete {{topic}}?"
confirmed-click="deletePermConfig(item, topic, 'topic')">{{'DELETE' | translate}}</a>
</td>
</tr>
</table>
</td>
<td class="text-center">
<table ng-repeat="group in item.groupPerms" class="perm-table">
<tr>
<td class="perm-tg">{{group}}</td>
<td ng-show="writeOperationEnabled" class="center"><a
href="javascript:;"
ng-click="openUpdateGroupDialog(item, group)">
{{'UPDATE' | translate}}</a></td>
<td ng-show="writeOperationEnabled"><a href="javascript:;"
ng-confirm-click="Are you sure to delete {{group}}?"
confirmed-click="deletePermConfig(item, group, 'group')">{{'DELETE' | translate}}</a>
</td>
</tr>
</table>
</td>
<td ng-show="writeOperationEnabled" class="text-center">
<button class="btn btn-raised btn-sm btn-primary" type="button"
ng-click="openAddTopicDialog(item)">
{{'ADD' | translate}}topic
</button>
<button class="btn btn-raised btn-sm btn-primary" type="button"
ng-click="openAddGroupDialog(item)">
{{'ADD' | translate}}group
</button>
<button class="btn btn-raised btn-sm btn-primary" type="button"
ng-click="openUpdateDialog(item)">
{{'UPDATE' | translate}}
</button>
<button class="btn btn-raised btn-sm btn-danger" type="button"
ng-confirm-click="Are you sure to delete {{item.accessKey}}?"
confirmed-click="deleteAclConfig(item.accessKey)">{{'DELETE' | translate}}
</button>
<button class="btn btn-raised btn-sm btn-danger" type="button"
ng-click="synchronizeData(item)">{{'SYNCHRONIZE' | translate}}
</button>
</td>
</tr>
</table>
<tm-pagination conf="paginationConf"></tm-pagination>
</md-content>
</md-tab>
<md-tab label="Global White List">
<md-content class="md-padding" style="min-height:600px">
<form class="form-inline pull-left col-sm-12">
<button ng-show="writeOperationEnabled" class="btn btn-raised btn-sm btn-primary"
type="button"
ng-click="openAddAddrDialog()">{{'ADD' |
translate}}
</button>
<button ng-show="writeOperationEnabled" class="btn btn-raised btn-sm btn-danger"
type="button"
ng-confirm-click="Are you sure to synchronize white list to all broker int the cluster?"
confirmed-click="synchronizeWhiteList(allGlobalWhiteAddrs)">
{{'SYNCHRONIZE' | translate}}
</button>
</form>
<table class="table table-bordered">
<tr>
<th class="text-center">{{'WHITE_LIST' | translate}}</th>
<th ng-show="writeOperationEnabled" class="text-center">
{{'OPERATION' | translate}}
</th>
</tr>
<tr ng-repeat="item in allGlobalWhiteAddrs">
<td class="text-center">{{item}}
</td>
<td ng-show="writeOperationEnabled" class="text-center">
<button class="btn btn-raised btn-sm btn-danger" type="button"
ng-confirm-click="Are you sure to delete {{item}}?"
confirmed-click="deleteGlobalWhiteAddr(item)">{{'DELETE' | translate}}
</button>
</td>
</tr>
</table>
</md-content>
</md-tab>
</md-tabs>
</md-content>
</div>
</div>
</div>
<script type="text/ng-template" id="addAclAccountDialog">
<div class="modal-header">
<h4 class="modal-title">{{'ADD' | translate }}</h4>
</div>
<div class="modal-body ">
<form id="addAppForm" name="addAppForm" class="form-horizontal" novalidate>
<div class="form-group">
<label class="control-label col-sm-2">Access Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.accessKey" type="text" required/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Secret Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.secretKey" type="text" required/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'IS_ADMIN' | translate}}:</label>
<div class="col-sm-8">
<md-switch class="md-primary" md-no-ink aria-label="Switch No Ink"
ng-model="ngDialogData.admin">
</md-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'DEFAULT_TOPIC_PERM' | translate}}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.defaultTopicPerm" type="text" readonly/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'DEFAULT_GROUP_PERM' | translate}}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.defaultGroupPerm" type="text" readonly/>
</div>
</div>
</form>
<div class="modal-footer">
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary"
ng-click="addRequest({'accessKey':ngDialogData.accessKey, 'secretKey': ngDialogData.secretKey, 'admin': ngDialogData.admin, 'defaultTopicPerm': ngDialogData.defaultTopicPerm, 'defaultGroupPerm': ngDialogData.defaultGroupPerm})">
{{ 'COMMIT' | translate }}
</button>
<button type="button" class="ngdialog-button ngdialog-button-secondary"
ng-click="closeThisDialog('Cancel')">{{ 'CLOSE' | translate }}
</button>
</div>
</div>
</div>
</script>
<script type="text/ng-template" id="updateAclAccountDialog">
<div class="modal-header">
<h4 class="modal-title">{{'UPDATE' | translate }}</h4>
</div>
<div class="modal-body ">
<form id="updateAccountForm" name="updateAccountForm" class="form-horizontal" novalidate>
<div class="form-group">
<label class="control-label col-sm-2">Access Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.accessKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Secret Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.secretKey" type="text" required/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'IS_ADMIN' | translate}}:</label>
<div class="col-sm-8">
<md-switch class="md-primary" md-no-ink aria-label="Switch No Ink"
ng-model="ngDialogData.admin">
</md-switch>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'DEFAULT_TOPIC_PERM' | translate}}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.defaultTopicPerm" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'DEFAULT_GROUP_PERM' | translate}}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.defaultGroupPerm" type="text" disabled/>
</div>
</div>
</form>
<div class="modal-footer">
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary"
ng-click="updateAclAccountRequest({'accessKey':ngDialogData.accessKey, 'secretKey': ngDialogData.secretKey, 'admin': ngDialogData.admin, 'defaultTopicPerm': ngDialogData.defaultTopicPerm, 'defaultGroupPerm': ngDialogData.defaultGroupPerm})">
{{ 'COMMIT' | translate }}
</button>
<button type="button" class="ngdialog-button ngdialog-button-secondary"
ng-click="closeThisDialog('Cancel')">{{ 'CLOSE' | translate }}
</button>
</div>
</div>
</div>
</script>
<script type="text/ng-template" id="addAclTopicDialog">
<div class="modal-header">
<h4 class="modal-title">{{'ADD' | translate }}{{'TOPIC_PERM' | translate }}</h4>
</div>
<div class="modal-body ">
<form id="addAclTopicForm" name="addAclTopicForm" class="form-horizontal" novalidate>
<div class="form-group">
<label class="control-label col-sm-2">Access Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.accessKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Secret Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.secretKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'TOPIC' | translate}}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="topic" type="text" required/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'TOPIC_PERM' | translate}}:</label>
<div class="col-sm-8">
<md-checkbox class="md-primary" ng-model="ngDialogData.pub">PUB</md-checkbox>
<md-checkbox class="md-primary" ng-model="ngDialogData.sub">SUB</md-checkbox>
<md-checkbox class="md-primary" ng-model="ngDialogData.deny">DENY</md-checkbox>
</div>
</div>
</form>
<div class="modal-footer">
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary"
ng-click="updateAclAccountRequest({'originalData':ngDialogData,'topic': topic , 'pub': ngDialogData.pub, 'sub': ngDialogData.sub, 'deny': ngDialogData.deny})">
{{ 'COMMIT' | translate }}
</button>
<button type="button" class="ngdialog-button ngdialog-button-secondary"
ng-click="closeThisDialog('Cancel')">{{ 'CLOSE' | translate }}
</button>
</div>
</div>
</div>
</script>
<script type="text/ng-template" id="updateAclTopicDialog">
<div class="modal-header">
<h4 class="modal-title">{{'UPDATE' | translate }}{{'TOPIC_PERM' | translate }}</h4>
</div>
<div class="modal-body ">
<form id="updateAclTopicForm" name="updateAclTopicForm" class="form-horizontal" novalidate>
<div class="form-group">
<label class="control-label col-sm-2">Access Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.accessKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Secret Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.secretKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'TOPIC' | translate}}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.topic" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'TOPIC_PERM' | translate}}:</label>
<div class="col-sm-8">
<md-checkbox class="md-primary" ng-model="ngDialogData.pub">PUB</md-checkbox>
<md-checkbox class="md-primary" ng-model="ngDialogData.sub">SUB</md-checkbox>
<md-checkbox class="md-primary" ng-model="ngDialogData.deny">DENY</md-checkbox>
</div>
</div>
</form>
<div class="modal-footer">
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary"
ng-click="updateAclAccountRequest({'originalData':ngDialogData,'topic': ngDialogData.topic , 'pub': ngDialogData.pub, 'sub': ngDialogData.sub, 'deny': ngDialogData.deny})">
{{ 'COMMIT' | translate }}
</button>
<button type="button" class="ngdialog-button ngdialog-button-secondary"
ng-click="closeThisDialog('Cancel')">{{ 'CLOSE' | translate }}
</button>
</div>
</div>
</div>
</script>
<script type="text/ng-template" id="addAclGroupDialog">
<div class="modal-header">
<h4 class="modal-title">{{'ADD' | translate }}{{'GROUP_PERM' | translate }}</h4>
</div>
<div class="modal-body ">
<form id="addAclGroupForm" name="addAclGroupForm" class="form-horizontal" novalidate>
<div class="form-group">
<label class="control-label col-sm-2">Access Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.accessKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Secret Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.secretKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'CONSUMER' | translate}}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="group" type="text" required/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'GROUP_PERM' | translate}}:</label>
<div class="col-sm-8">
<md-checkbox class="md-primary" ng-model="ngDialogData.pub">PUB</md-checkbox>
<md-checkbox class="md-primary" ng-model="ngDialogData.sub">SUB</md-checkbox>
<md-checkbox class="md-primary" ng-model="ngDialogData.deny">DENY</md-checkbox>
</div>
</div>
</form>
<div class="modal-footer">
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary"
ng-click="updateAclAccountRequest({'originalData':ngDialogData,'group': group , 'pub': ngDialogData.pub, 'sub': ngDialogData.sub, 'deny': ngDialogData.deny})">
{{ 'COMMIT' | translate }}
</button>
<button type="button" class="ngdialog-button ngdialog-button-secondary"
ng-click="closeThisDialog('Cancel')">{{ 'CLOSE' | translate }}
</button>
</div>
</div>
</div>
</script>
<script type="text/ng-template" id="updateAclGroupDialog">
<div class="modal-header">
<h4 class="modal-title">{{'UPDATE' | translate }}{{'GROUP_PERM' | translate }}</h4>
</div>
<div class="modal-body ">
<form id="updateAclGroupForm" name="updateAclGroupForm" class="form-horizontal" novalidate>
<div class="form-group">
<label class="control-label col-sm-2">Access Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.accessKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Secret Key:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.secretKey" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'CONSUMER' | translate}}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ngDialogData.group" type="text" disabled/>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{'GROUP_PERM' | translate}}:</label>
<div class="col-sm-8">
<md-checkbox class="md-primary" ng-model="ngDialogData.pub">PUB</md-checkbox>
<md-checkbox class="md-primary" ng-model="ngDialogData.sub">SUB</md-checkbox>
<md-checkbox class="md-primary" ng-model="ngDialogData.deny">DENY</md-checkbox>
</div>
</div>
</form>
<div class="modal-footer">
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary"
ng-click="updateAclAccountRequest({'originalData':ngDialogData,'group': ngDialogData.group , 'pub': ngDialogData.pub, 'sub': ngDialogData.sub, 'deny': ngDialogData.deny})">
{{ 'COMMIT' | translate }}
</button>
<button type="button" class="ngdialog-button ngdialog-button-secondary"
ng-click="closeThisDialog('Cancel')">{{ 'CLOSE' | translate }}
</button>
</div>
</div>
</div>
</script>
<script type="text/ng-template" id="addWhiteListDialog">
<div class="modal-header">
<h4 class="modal-title">{{'ADD' | translate }}{{'WHITE_LIST' | translate }}</h4>
</div>
<div class="modal-body ">
<form id="addWhiteListForm" name="addWhiteListForm" class="form-horizontal" novalidate>
<div class="form-group">
<label class="control-label col-sm-2">{{'WHITE_LIST' | translate }}:</label>
<div class="col-sm-10">
<input class="form-control" ng-model="ip" type="text"/>
</div>
</div>
</form>
<div class="modal-footer">
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary"
ng-click="addWhiteListRequest(ip)">
{{ 'COMMIT' | translate }}
</button>
<button type="button" class="ngdialog-button ngdialog-button-secondary"
ng-click="closeThisDialog('Cancel')">{{ 'CLOSE' | translate }}
</button>
</div>
</div>
</div>
</script>