This is an automated email from the ASF dual-hosted git repository.

sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar-manager.git


The following commit(s) were added to refs/heads/master by this push:
     new c50cff9  Display front end by different role (#238)
c50cff9 is described below

commit c50cff97715ce10453264f3930110f7d49f94c6e
Author: Guangning <[email protected]>
AuthorDate: Mon Jan 13 17:17:01 2020 +0800

    Display front end by different role (#238)
    
    ### Motivation
    This is the fourth pr of task #14.
    After merge this pr, the platform will have complete multi-tenant 
capability, the front end will display different contents according to the 
user's role, and the back end route will filter resources according to 
different roles.
    
    
    ### Modifications
    
    * The front-end supports displaying different content according to 
different roles.
    * Super users can view everything
    * Support to initialize superuser via rest api
    
    ### Verifying this change
    Add unit test
---
 front-end/src/api/users.js                         |   7 +
 front-end/src/router/index.js                      | 180 ++++++++++---
 front-end/src/store/modules/permission.js          |   3 +-
 front-end/src/store/modules/user.js                |  40 ++-
 front-end/src/views/login/index.vue                |   8 +-
 .../src/views/management/admin/tenants/tenant.vue  | 290 +++++++++++++++++++++
 .../src/views/management/clusters/cluster.vue      |   5 +-
 .../src/views/management/environments/index.vue    |  19 +-
 front-end/src/views/management/roles/index.vue     |  17 +-
 .../manager/controller/ClustersController.java     |  18 +-
 .../manager/controller/EnvironmentsController.java | 101 ++++++-
 .../pulsar/manager/controller/LoginController.java |  31 ++-
 .../manager/controller/RoleBindingController.java  |   6 +
 .../pulsar/manager/controller/RolesController.java |  41 +--
 .../manager/controller/TenantsController.java      |  76 +++++-
 .../pulsar/manager/controller/UsersController.java | 153 ++++++++++-
 .../manager/dao/EnvironmentsRepositoryImpl.java    |   5 +
 .../manager/dao/RoleBindingRepositoryImpl.java     |   5 +
 .../pulsar/manager/dao/RolesRepositoryImpl.java    |  10 +
 .../manager/entity/EnvironmentsRepository.java     |   2 +
 .../manager/entity/RoleBindingRepository.java      |   6 +
 .../pulsar/manager/entity/RolesRepository.java     |  14 +-
 .../apache/pulsar/manager/entity/TenantEntity.java |   3 +
 .../interceptor/AdminHandlerInterceptor.java       |  76 ++++--
 .../manager/interceptor/WebAppConfigurer.java      |   1 +
 .../pulsar/manager/mapper/EnvironmentsMapper.java  |   6 +
 .../pulsar/manager/mapper/RoleBindingMapper.java   |   4 +
 .../apache/pulsar/manager/mapper/RolesMapper.java  |  12 +
 .../pulsar/manager/mapper/TenantsMapper.java       |  19 +-
 .../{PulsarEvent.java => PermissionsService.java}  |   7 +-
 .../apache/pulsar/manager/service/PulsarEvent.java |   4 +
 .../pulsar/manager/service/RoleBindingService.java |   2 +
 .../pulsar/manager/service/RolesService.java       |   4 +-
 .../PermissionsServiceImpl.java}                   |  10 +-
 .../manager/service/impl/PulsarEventImpl.java      | 110 +++++++-
 .../service/impl/RoleBindingServiceImpl.java       |  34 +++
 .../manager/service/impl/RolesServiceImpl.java     |  82 +++---
 .../pulsar/manager/zuul/EnvironmentForward.java    |  26 +-
 src/main/resources/META-INF/sql/herddb-schema.sql  |  28 +-
 src/main/resources/META-INF/sql/mysql-schema.sql   |  12 +-
 .../resources/META-INF/sql/postgresql-schema.sql   |  12 +-
 src/main/resources/META-INF/sql/sqlite-schema.sql  |  13 +-
 .../manager/dao/NamespacesRepositoryImplTest.java  |   3 +-
 .../manager/dao/TenantsRepositoryImplTest.java     |   8 +
 .../manager/service/PulsarEventImplTest.java       | 192 ++++++++++++++
 45 files changed, 1470 insertions(+), 235 deletions(-)

diff --git a/front-end/src/api/users.js b/front-end/src/api/users.js
index 65e46a3..58d9538 100644
--- a/front-end/src/api/users.js
+++ b/front-end/src/api/users.js
@@ -53,3 +53,10 @@ export function deleteUser(data) {
   })
 }
 
+export function getUserInfo() {
+  return request({
+    headers: { 'Content-Type': 'application/json' },
+    url: SPRING_BASE_URL + '/users/userInfo',
+    method: 'get'
+  })
+}
diff --git a/front-end/src/router/index.js b/front-end/src/router/index.js
index dd253c5..e3f878c 100644
--- a/front-end/src/router/index.js
+++ b/front-end/src/router/index.js
@@ -68,11 +68,24 @@ export const constantRouterMap = [
     path: '/401',
     component: () => import('@/views/errorPage/401'),
     hidden: true
-  },
+  }
+]
+
+export default new Router({
+  // mode: 'history', // require service support
+  scrollBehavior: () => ({ y: 0 }),
+  routes: constantRouterMap
+})
+
+export const asyncRouterMap = [
+
   {
     path: '/environments',
     component: () => import('@/views/management/environments/index'),
-    hidden: true
+    hidden: true,
+    meta: {
+      roles: ['super', 'admin']
+    }
   },
   {
     path: '',
@@ -80,7 +93,8 @@ export const constantRouterMap = [
     redirect: 'management/tenants',
     meta: {
       title: 'Dashboard',
-      icon: 'dashboard'
+      icon: 'dashboard',
+      roles: ['super']
     },
     hidden: true,
     children: [
@@ -102,171 +116,260 @@ export const constantRouterMap = [
     path: '/management',
     component: Layout,
     name: 'Management',
-    redirect: 'management/tenants',
+    redirect: 'management/roles',
     meta: {
       title: 'Management',
-      icon: 'component'
+      icon: 'component',
+      roles: ['super', 'admin']
     },
     children: [
       {
         path: 'clusters',
         component: () => import('@/views/management/clusters/index'),
         name: 'Clusters',
-        meta: { title: 'Clusters', noCache: true }
+        meta: {
+          title: 'Clusters',
+          noCache: true,
+          roles: ['super']
+        }
       },
       {
         path: 'clusters/:cluster/cluster',
         component: () => import('@/views/management/clusters/cluster'),
         name: 'ClusterInfo',
-        meta: { title: 'ClusterInfo', noCache: true },
+        meta: {
+          title: 'ClusterInfo',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: 'clusters/:cluster/:failureDomainName/failureDomainName',
         component: () => import('@/views/management/clusters/failureDomain'),
         name: 'FailureDomainInfo',
-        meta: { title: 'FailureDomainInfo', noCache: true },
+        meta: {
+          title: 'FailureDomainInfo',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: 'clusters/:cluster/:namespaceIsolation/namespaceIsolationPolicy',
         component: () => 
import('@/views/management/namespaceIsolations/namespaceIsolationPolicy'),
         name: 'NamespaceIsolationPolicy',
-        meta: { title: 'NamespaceIsolationPolicy', noCache: true },
+        meta: {
+          title: 'NamespaceIsolationPolicy',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: 'brokers/:cluster/:broker/broker',
         component: () => import('@/views/management/brokers/broker'),
         name: 'BrokerInfo',
-        meta: { title: 'BrokerInfo', noCache: true },
+        meta: {
+          title: 'BrokerInfo',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: 'tenants',
         component: () => import('@/views/management/tenants/index'),
         name: 'Tenants',
-        meta: { title: 'Tenants', noCache: true }
+        meta: {
+          title: 'Tenants',
+          noCache: true,
+          roles: ['super']
+        }
       },
       {
         path: 'tenants/tenantInfo/:tenant',
         component: () => import('@/views/management/tenants/tenant'),
         name: 'Tenant',
-        meta: { title: 'TenantInfo', noCache: true },
+        meta: {
+          title: 'TenantInfo',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
+        path: 'admin/tenants/tenantInfo',
+        component: () => import('@/views/management/admin/tenants/tenant'),
+        name: 'Tenant Admin',
+        meta: {
+          title: 'TenantInfo',
+          noCache: true,
+          roles: ['super', 'admin']
+        }
+      },
+      {
         path: 'tenants/tenantInfo/public?tab=namespaces',
         name: 'Namespaces',
-        meta: { title: 'Namespaces', noCache: true }
+        meta: {
+          title: 'Namespaces',
+          noCache: true,
+          roles: ['super']
+        }
       },
       {
         path: 'namespaces/public/default/namespace?tab=topics',
         name: 'Topics',
-        meta: { title: 'Topics', noCache: true }
+        meta: {
+          title: 'Topics',
+          noCache: true,
+          roles: ['super']
+        }
       },
       {
         path: 'topics/:persistent/:tenant/:namespace/:topic/topic',
         component: () => import('@/views/management/topics/topic'),
         name: 'TopicInfo',
-        meta: { title: 'TopicInfo', noCache: true },
+        meta: {
+          title: 'TopicInfo',
+          noCache: true,
+          roles: ['super', 'admin']
+        },
         hidden: true
       },
       {
         path: 'topics/:persistent/:tenant/:namespace/:topic/partitionedTopic',
         component: () => import('@/views/management/topics/partitionedTopic'),
         name: 'ParititionTopicInfo',
-        meta: { title: 'ParititionTopicInfo', noCache: true },
+        meta: {
+          title: 'ParititionTopicInfo',
+          noCache: true,
+          roles: ['super', 'admin']
+        },
         hidden: true
       },
       {
         path: 
'subscriptions/:persistent/:tenant/:namespace/:topic/:subscription/subscription',
         component: () => 
import('@/views/management/subscriptions/subscription'),
         name: 'SubscriptionInfo',
-        meta: { title: 'SubscriptionInfo', noCache: true },
+        meta: {
+          title: 'SubscriptionInfo',
+          noCache: true,
+          roles: ['super', 'admin']
+        },
         hidden: true
       },
       {
         path: 'namespaces/:tenant',
         name: 'NamespacesTenant',
-        meta: { title: 'Namespaces', noCache: true },
+        meta: {
+          title: 'Namespaces',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: 'namespaces/:tenant/:namespace/namespace',
         component: () => import('@/views/management/namespaces/namespace'),
         name: 'NamespacesInfo',
-        meta: { title: 'NamespacesInfo', noCache: true },
+        meta: {
+          title: 'NamespacesInfo',
+          noCache: true,
+          roles: ['super', 'admin']
+        },
         hidden: true
       },
       {
         path: 'functions',
         component: () => import('@/views/management/functions'),
         name: 'Functions',
-        meta: { title: 'Functions', noCache: true },
+        meta: {
+          title: 'Functions',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: 'sources',
         component: () => import('@/views/management/sources'),
         name: 'Sources',
-        meta: { title: 'Sources', noCache: true },
+        meta: {
+          title: 'Sources',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: 'sinks',
         component: () => import('@/views/management/sinks'),
         name: 'Sinks',
-        meta: { title: 'Sinks', noCache: true },
+        meta: {
+          title: 'Sinks',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: 'bookies',
         component: () => import('@/views/management/bookies'),
         name: 'Bookies',
-        meta: { title: 'Bookies', noCache: true },
+        meta: {
+          title: 'Bookies',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: true
       },
       {
         path: '/users',
         component: () => import('@/views/management/users/index'),
         name: 'Users',
-        meta: { title: 'Users', noCache: true },
+        meta: {
+          title: 'Users',
+          noCache: true,
+          roles: ['super']
+        },
         hidden: false
       },
       {
         path: '/roles',
         component: () => import('@/views/management/roles/index'),
         name: 'Roles',
-        meta: { title: 'Roles', noCache: true },
+        meta: {
+          title: 'Roles',
+          noCache: true,
+          roles: ['super', 'admin']
+        },
         hidden: false
       },
       {
         path: '/roleBinding',
         component: () => import('@/views/management/roleBinding/index'),
         name: 'RoleBinding',
-        meta: { title: 'RoleBinding', noCache: true },
+        meta: {
+          title: 'RoleBinding',
+          noCache: true,
+          roles: ['super', 'admin']
+        },
         hidden: false
       },
       {
         path: '/tokens',
         component: () => import('@/views/management/tokens/index'),
         name: 'Tokens',
-        meta: { title: 'Tokens', noCache: true },
+        meta: {
+          title: 'Tokens',
+          noCache: true,
+          roles: ['super', 'admin']
+        },
         hidden: false
       }
     ]
-  }
-]
-
-export default new Router({
-  // mode: 'history', // require service support
-  scrollBehavior: () => ({ y: 0 }),
-  routes: constantRouterMap
-})
-
-export const asyncRouterMap = [
-
+  },
   {
     path: 'external-link',
     component: Layout,
@@ -277,6 +380,5 @@ export const asyncRouterMap = [
       }
     ]
   },
-
   { path: '*', redirect: '/404', hidden: true }
 ]
diff --git a/front-end/src/store/modules/permission.js 
b/front-end/src/store/modules/permission.js
index f70d208..6461d88 100644
--- a/front-end/src/store/modules/permission.js
+++ b/front-end/src/store/modules/permission.js
@@ -12,6 +12,7 @@
  * limitations under the License.
  */
 import { asyncRouterMap, constantRouterMap } from '@/router'
+// import store from '@/store'
 
 /**
  * 通过meta.role判断是否与当前用户权限匹配
@@ -63,7 +64,7 @@ const permission = {
       return new Promise(resolve => {
         const { roles } = data
         let accessedRouters
-        if (roles.includes('admin')) {
+        if (roles.includes('super')) {
           accessedRouters = asyncRouterMap
         } else {
           accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
diff --git a/front-end/src/store/modules/user.js 
b/front-end/src/store/modules/user.js
index 2f6cc3b..0bae227 100644
--- a/front-end/src/store/modules/user.js
+++ b/front-end/src/store/modules/user.js
@@ -11,12 +11,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { loginByUsername, logout, getUserInfo } from '@/api/login'
+import { loginByUsername, logout } from '@/api/login'
 import { getToken, setToken, removeToken } from '@/utils/auth'
 import { setName, removeName } from '@/utils/username'
 import { removeEnvironment } from '@/utils/environment'
 import { Message } from 'element-ui'
 import { setTenant, removeTenant } from '../../utils/tenant'
+import { getUserInfo } from '@/api/users'
 
 const user = {
   state: {
@@ -87,19 +88,12 @@ const user = {
     // 获取用户信息
     GetUserInfo({ commit, state }) {
       return new Promise((resolve, reject) => {
-        // const response = getUserInfo(state.token)
-        // const data = response.data
-
-        commit('SET_ROLES', ['admin'])
-        commit('SET_NAME', 'admin')
-        // commit('SET_AVATAR', 'data.avatar')
-        commit('SET_INTRODUCTION', 'Pulsar Manager')
-        const response = {
-          'data': {
-            'roles': ['admin']
-          }
-        }
-        resolve(response)
+        getUserInfo().then(response => {
+          commit('SET_ROLES', response.data.roles)
+          commit('SET_NAME', 'admin')
+          commit('SET_INTRODUCTION', 'Pulsar Manager')
+          resolve(response)
+        })
       })
     },
 
@@ -143,15 +137,15 @@ const user = {
       return new Promise(resolve => {
         commit('SET_TOKEN', role)
         setToken(role)
-        getUserInfo(role).then(response => {
-          const data = response.data
-          commit('SET_ROLES', data.roles)
-          commit('SET_NAME', data.name)
-          commit('SET_AVATAR', data.avatar)
-          commit('SET_INTRODUCTION', data.introduction)
-          dispatch('GenerateRoutes', data) // 动态修改权限后 重绘侧边菜单
-          resolve()
-        })
+        // getUserInfo(role).then(response => {
+        //   const data = response.data
+        //   commit('SET_ROLES', data.roles)
+        //   commit('SET_NAME', data.name)
+        //   commit('SET_AVATAR', data.avatar)
+        //   commit('SET_INTRODUCTION', data.introduction)
+        //   dispatch('GenerateRoutes', data) // 动态修改权限后 重绘侧边菜单
+        //   resolve()
+        // })
       })
     }
   }
diff --git a/front-end/src/views/login/index.vue 
b/front-end/src/views/login/index.vue
index 3d95039..f94bb63 100644
--- a/front-end/src/views/login/index.vue
+++ b/front-end/src/views/login/index.vue
@@ -53,9 +53,9 @@
       </el-form-item>
 
       <el-button :loading="loading" type="primary" 
style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">{{ 
$t('login.logIn') }}</el-button>
-      <el-button class="thirdparty-button" type="primary" 
@click="showDialog=true">
+      <!-- <el-button class="thirdparty-button" type="primary" 
@click="showDialog=true">
         Or connect with
-      </el-button>
+      </el-button> -->
     </el-form>
 
     <el-dialog :title="$t('login.thirdparty')" :visible.sync="showDialog" 
append-to-body>
@@ -120,7 +120,7 @@ export default {
     // window.addEventListener('hashchange', this.afterQRScan)
   },
   destroyed() {
-    // window.removeEventListener('hashchange', this.afterQRScan)
+    window.removeEventListener('hashchange', this.afterQRScan)
   },
   mounted() {
     window.addEventListener('message', this.handleMessage)
@@ -145,7 +145,7 @@ export default {
           this.loading = true
           this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
             this.loading = false
-            this.$router.push({ path: this.redirect || '/management/clusters' 
})
+            this.$router.push({ path: this.redirect || '/management/roles' })
           }).catch(() => {
             this.loading = false
           })
diff --git a/front-end/src/views/management/admin/tenants/tenant.vue 
b/front-end/src/views/management/admin/tenants/tenant.vue
new file mode 100644
index 0000000..f380924
--- /dev/null
+++ b/front-end/src/views/management/admin/tenants/tenant.vue
@@ -0,0 +1,290 @@
+<!--
+
+    Licensed 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.
+
+-->
+<template>
+  <div class="app-container">
+    <div class="createPost-container">
+      <el-form :inline="true" :model="postForm" class="form-container">
+        <el-form-item class="postInfo-container-item" label="Tenant">
+          <el-select v-model="postForm.tenant" 
:placeholder="$t('tenant.selectTenantMessage')" 
@change="getNamespacesList(postForm.tenant)">
+            <el-option v-for="(item,index) in tenantsListOptions" 
:key="item+index" :label="item" :value="item"/>
+          </el-select>
+        </el-form-item>
+      </el-form>
+    </div>
+    <el-tabs v-model="activeName">
+      <el-tab-pane :label="$t('tabs.namespace')" name="namespaces">
+        <div class="filter-container">
+          <el-input
+            :placeholder="$t('namespace.searchNamespaces')"
+            v-model="searchNamespace"
+            style="width: 200px;"
+            @keyup.enter.native="handleFilterNamespace"/>
+          <el-button type="primary" icon="el-icon-search" 
@click="handleFilterNamespace"/>
+          <el-button type="primary" icon="el-icon-plus" 
@click="handleCreateNamespace">{{ $t('namespace.newNamespace') }}</el-button>
+        </div>
+        <el-row :gutter="24">
+          <el-col :xs="{span: 24}" :sm="{span: 24}" :md="{span: 24}" 
:lg="{span: 24}" :xl="{span: 24}">
+            <el-table
+              v-loading="listLoading"
+              :key="tableKey"
+              :data="listNamespaces"
+              border
+              fit
+              highlight-current-row
+              style="width: 100%;">
+              <el-table-column :label="$t('namespace.name')" align="center">
+                <template slot-scope="scope">
+                  <router-link :to="'/management/namespaces/' + 
scope.row.tenant +'/' + scope.row.namespace + '/namespace?tab=overview'" 
class="link-type">
+                    <span>{{ scope.row.namespace }}</span>
+                  </router-link>
+                </template>
+              </el-table-column>
+              <el-table-column :label="$t('topic.topicNumber')" align="center">
+                <template slot-scope="scope">
+                  <router-link :to="'/management/namespaces/' + 
scope.row.tenant + '/' + scope.row.namespace + '/namespace?tab=topics'" 
class="link-type">
+                    <span>{{ scope.row.topics }}</span>
+                  </router-link>
+                </template>
+              </el-table-column>
+              <el-table-column :label="$t('table.actions')" align="center" 
class-name="small-padding fixed-width">
+                <template slot-scope="scope">
+                  <router-link :to="'/management/namespaces/' + 
scope.row.tenant +'/' + scope.row.namespace + '/namespace'">
+                    <el-button type="primary" size="mini">{{ $t('table.edit') 
}}</el-button>
+                  </router-link>
+                  <el-button v-if="scope.row.status!='deleted'" size="mini" 
type="danger" @click="handleDeleteNamespace(scope.row)">{{ $t('table.delete') 
}}</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-col>
+        </el-row>
+      </el-tab-pane>
+    </el-tabs>
+    <el-dialog :title="textMap[dialogStatus]" 
:visible.sync="dialogFormVisible" width="30%">
+      <el-form ref="temp" :model="temp" :rules="rules" label-position="top">
+        <el-form-item v-if="dialogStatus==='createNamespace'" 
:label="$t('table.namespace')" prop="namespace">
+          <el-input v-model="temp.namespace" 
:placeholder="$t('namespace.inputNamespaceMessage')"/>
+        </el-form-item>
+        <el-form-item v-if="dialogStatus==='deleteNamespace'">
+          <h4>{{ $t('namespace.deleteNamespaceMessage') }}</h4>
+        </el-form-item>
+        <el-form-item v-if="dialogStatus==='deleteTenant'">
+          <h4>{{ $t('tenant.deleteTenantMessage') }}</h4>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleOptions()">{{ 
$t('table.confirm') }}</el-button>
+          <el-button @click="dialogFormVisible=false">{{ $t('table.cancel') 
}}</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { fetchTenants } from '@/api/tenants'
+import { getTenant } from '@/utils/tenant'
+import {
+  fetchNamespaces,
+  putNamespace,
+  deleteNamespace
+} from '@/api/namespaces'
+import { validateEmpty } from '@/utils/validate'
+
+const defaultForm = {
+  tenant: getTenant()
+}
+
+export default {
+  name: 'TenantInfo',
+  data() {
+    return {
+      postForm: Object.assign({}, defaultForm),
+      adminRoles: '',
+      tenantsListOptions: [],
+      listQuery: {
+        namespace: '',
+        page: 1,
+        limit: 20
+      },
+      activeName: 'namespaces',
+      listLoading: false,
+      tableKey: 0,
+      total: 0,
+      listNamespaces: [],
+      temp: {
+        tenant: '',
+        namespace: '',
+        limit: ''
+      },
+      dialogFormVisible: false,
+      dialogStatus: '',
+      rules: {
+        namespace: [{ required: true, message: 
this.$i18n.t('namespace.namespaceNameIsRequired'), trigger: 'blur' }]
+      },
+      currentTabName: '',
+      textMap: {
+        createNamespace: this.$i18n.t('namespace.newNamespace'),
+        deleteNamespace: this.$i18n.t('namespace.deleteNamespace')
+      },
+      tempNamespacesList: [],
+      searchNamespace: '',
+      searchList: []
+    }
+  },
+  created() {
+    this.getRemoteTenantsList()
+    this.getNamespacesList()
+  },
+  methods: {
+    getRemoteTenantsList() {
+      fetchTenants().then(response => {
+        if (!response.data) return
+        for (var i = 0; i < response.data.total; i++) {
+          this.tenantsListOptions.push(response.data.data[i].tenant)
+        }
+      })
+    },
+    getNamespacesList() {
+      fetchNamespaces(this.postForm.tenant, this.listQuery).then(response => {
+        if (!response.data.data) return
+        this.listNamespaces = []
+        for (var i = 0; i < response.data.data.length; i++) {
+          this.listNamespaces.push({
+            'tenant': this.postForm.tenant,
+            'namespace': response.data.data[i].namespace,
+            'topics': response.data.data[i].topics
+          })
+        }
+        this.total = this.listNamespaces.length
+        // Just to simulate the time of the request
+        setTimeout(() => {
+          this.listLoading = false
+        }, 1.5 * 1000)
+      })
+    },
+    handleFilterNamespace() {
+      if (this.tempNamespacesList.length <= 0) {
+        for (var t = 0; t < this.listNamespaces.length; t++) {
+          this.tempNamespacesList.push(this.listNamespaces[t])
+        }
+      }
+      if (!validateEmpty(this.searchNamespace)) {
+        this.searchList = []
+        for (var i = 0; i < this.listNamespaces.length; i++) {
+          if 
(this.listNamespaces[i]['namespace'].indexOf(this.searchNamespace) !== -1) {
+            this.searchList.push(this.listNamespaces[i])
+          }
+        }
+        this.listNamespaces = this.searchList
+      } else {
+        this.listNamespaces = this.tempNamespacesList
+      }
+    },
+    handleCreateNamespace() {
+      this.temp.namespace = ''
+      this.dialogStatus = 'createNamespace'
+      this.dialogFormVisible = true
+    },
+    createNamespace() {
+      putNamespace(this.postForm.tenant, this.temp.namespace, 
this.temp).then(() => {
+        this.listNamespaces = []
+        this.getNamespacesList()
+        this.dialogFormVisible = false
+        this.$notify({
+          title: 'success',
+          message: this.$i18n.t('namespace.createNsSuccessNotification'),
+          type: 'success',
+          duration: 2000
+        })
+      })
+    },
+    handleOptions() {
+      this.$refs['temp'].validate((valid) => {
+        if (valid) {
+          switch (this.dialogStatus) {
+            case 'createNamespace':
+              this.createNamespace()
+              break
+            case 'deleteNamespace':
+              this.deleteNamespace()
+              break
+          }
+        }
+      })
+    },
+    handleDeleteNamespace(row) {
+      this.dialogStatus = 'deleteNamespace'
+      this.dialogFormVisible = true
+      this.temp.tenant = row.tenant
+      this.temp.namespace = row.namespace
+    },
+    deleteNamespace() {
+      var tenantNamespace = this.temp.tenant + '/' + this.temp.namespace
+      deleteNamespace(tenantNamespace).then((response) => {
+        this.$notify({
+          title: 'success',
+          message: this.$i18n.t('namespace.deleteNsSuccessNotification'),
+          type: 'success',
+          duration: 2000
+        })
+        this.dialogFormVisible = false
+        this.listNamespaces = []
+        this.getNamespacesList()
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.el-tag + .el-tag {
+    margin-left: 10px;
+  }
+.button-new-tag {
+  margin-left: 10px;
+  height: 32px;
+  line-height: 30px;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+.input-new-tag {
+  width: 90px;
+  margin-left: 10px;
+  vertical-align: bottom;
+}
+.section-content {
+  margin-top: 15px;
+}
+.confirm-button {
+  margin-top: 10px;
+}
+.section-title {
+  color: rgba(0,0,0,.45);
+  font-size: 16px;
+}
+.component-item{
+  min-height: 60px;
+}
+.split-line {
+  background: #e6e9f3;
+  border: none;
+  height: 1px;
+}
+.danger-line {
+  background: red;
+  border: none;
+  height: 1px;
+}
+</style>
diff --git a/front-end/src/views/management/clusters/cluster.vue 
b/front-end/src/views/management/clusters/cluster.vue
index 7b59491..0cef36d 100644
--- a/front-end/src/views/management/clusters/cluster.vue
+++ b/front-end/src/views/management/clusters/cluster.vue
@@ -286,12 +286,14 @@ import MdInput from '@/components/MDinput'
 import { validateEmpty, validateServiceUrl } from '@/utils/validate'
 import { formatBytes, getQueryObject } from '@/utils/index'
 import { numberFormatter } from '@/filters/index'
+import permission from '@/directive/permission/index.js'
 
 const defaultForm = {
   cluster: ''
 }
 export default {
   name: 'ClusterInfo',
+  directives: { permission },
   components: {
     Pagination,
     MdInput
@@ -358,7 +360,8 @@ export default {
       deleteClusterMessage: this.$i18n.t('cluster.deleteClusterMessage'),
       deleteFdMessage: this.$i18n.t('fd.deleteFdMessage'),
       deletePolicyMessage: this.$i18n.t('ip.deletePolicyMessage'),
-      currentActiveTab: ''
+      currentActiveTab: '',
+      key: 1
     }
   },
   created() {
diff --git a/front-end/src/views/management/environments/index.vue 
b/front-end/src/views/management/environments/index.vue
index 0e50f1a..fc2dfac 100644
--- a/front-end/src/views/management/environments/index.vue
+++ b/front-end/src/views/management/environments/index.vue
@@ -15,7 +15,7 @@
 -->
 <template>
   <div class="app-container">
-    <el-button type="primary" icon="el-icon-plus" 
@click="handleCreateEnvironment">{{ $t('env.buttonNewEnv') }}</el-button>
+    <el-button v-if="superUser" type="primary" icon="el-icon-plus" 
@click="handleCreateEnvironment">{{ $t('env.buttonNewEnv') }}</el-button>
 
     <el-row :gutter="24">
       <el-col :xs="{span: 24}" :sm="{span: 24}" :md="{span: 24}" :lg="{span: 
24}" :xl="{span: 24}" style="margin-top:15px">
@@ -39,7 +39,7 @@
               <span>{{ scope.row.broker }}</span>
             </template>
           </el-table-column>
-          <el-table-column :label="$t('table.actions')" align="center" 
class-name="small-padding fixed-width">
+          <el-table-column v-if="superUser" :label="$t('table.actions')" 
align="center" class-name="small-padding fixed-width">
             <template slot-scope="scope">
               <el-button type="primary" size="mini" 
@click="handleUpdateEnvironment(scope.row)">{{ $t('table.edit') }}</el-button>
               <el-button size="mini" type="danger" 
@click="handleDeleteEnvironment(scope.row)">{{ $t('table.delete') }}</el-button>
@@ -78,6 +78,7 @@
 <script>
 import { putEnvironment, fetchEnvironments, deleteEnvironment, 
updateEnvironment } from '@/api/environments'
 import { setEnvironment } from '@/utils/environment'
+import store from '@/store'
 
 export default {
   name: 'EnvironmentInfo',
@@ -101,6 +102,8 @@ export default {
         'name': '',
         'broker': ''
       },
+      superUser: false,
+      roles: [],
       rules: {
         environment: [{ required: true, message: 
this.$i18n.t('env.envNameIsRequired'), trigger: 'blur' }],
         broker: [{ required: true, message: 
this.$i18n.t('env.serviceUrlIsRequired'), trigger: 'blur' }]
@@ -109,6 +112,12 @@ export default {
   },
   created() {
     this.getEnvironments()
+    this.roles = store.getters && store.getters.roles
+    if (this.roles.includes('super')) {
+      this.superUser = true
+    } else {
+      this.superUser = false
+    }
   },
   methods: {
     getEnvironments() {
@@ -238,7 +247,11 @@ export default {
     },
     handleSetEnvironment(environment) {
       setEnvironment(environment)
-      this.$router.push({ path: '/management/tenants' })
+      if (this.roles.includes('super')) {
+        this.$router.push({ path: '/management/tenants' })
+      } else {
+        this.$router.push({ path: '/management/admin/tenants/tenantInfo' })
+      }
     }
   }
 }
diff --git a/front-end/src/views/management/roles/index.vue 
b/front-end/src/views/management/roles/index.vue
index 54c8519..9c442f9 100644
--- a/front-end/src/views/management/roles/index.vue
+++ b/front-end/src/views/management/roles/index.vue
@@ -57,7 +57,13 @@
               <span>{{ scope.row.roleSource }}</span>
             </template>
           </el-table-column>
-          <el-table-column :label="$t('table.actions')" align="center" 
class-name="small-padding fixed-width">
+          <el-table-column v-if="superUser" :label="$t('table.actions')" 
align="center" class-name="small-padding fixed-width">
+            <template slot-scope="scope">
+              <el-button type="primary" size="mini" 
@click="handleUpdateRole(scope.row)">{{ $t('table.edit') }}</el-button>
+              <el-button size="mini" type="danger" 
@click="handleDeleteRole(scope.row)">{{ $t('table.delete') }}</el-button>
+            </template>
+          </el-table-column>
+          <el-table-column v-if="superUser === false" 
:label="$t('table.actions')" align="center" class-name="small-padding 
fixed-width">
             <template slot-scope="scope">
               <el-button :disabled="scope.row.resourceType=='TENANTS'" 
type="primary" size="mini" @click="handleUpdateRole(scope.row)">{{ 
$t('table.edit') }}</el-button>
               <el-button :disabled="scope.row.resourceType=='TENANTS'" 
size="mini" type="danger" @click="handleDeleteRole(scope.row)">{{ 
$t('table.delete') }}</el-button>
@@ -83,7 +89,7 @@
             v-model="form.resourceType"
             :placeholder="$t('role.resourceTypePlaceHolder')"
             style="width:100%"
-            @change="handleChangeResourceType(form.resourceType)">
+            @change="handleChangeResourceType(form)">
             <el-option
               v-for="item in resourceTypeListOptions"
               :key="item.value"
@@ -172,6 +178,7 @@ import {
   updateRole,
   deleteRole
 } from '@/api/roles'
+import store from '@/store'
 
 export default {
   name: 'RolesInfo',
@@ -222,6 +229,12 @@ export default {
     }
   },
   created() {
+    const roles = store.getters && store.getters.roles
+    if (roles.includes('super')) {
+      this.superUser = true
+    } else {
+      this.superUser = false
+    }
     this.getRoles()
     this.getResourceType()
   },
diff --git 
a/src/main/java/org/apache/pulsar/manager/controller/ClustersController.java 
b/src/main/java/org/apache/pulsar/manager/controller/ClustersController.java
index 92a3beb..54259e6 100644
--- a/src/main/java/org/apache/pulsar/manager/controller/ClustersController.java
+++ b/src/main/java/org/apache/pulsar/manager/controller/ClustersController.java
@@ -13,6 +13,7 @@
  */
 package org.apache.pulsar.manager.controller;
 
+import com.google.common.collect.Maps;
 import org.apache.pulsar.manager.service.ClustersService;
 import org.apache.pulsar.manager.service.EnvironmentCacheService;
 import io.swagger.annotations.Api;
@@ -20,6 +21,7 @@ import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
+import org.apache.pulsar.manager.service.RolesService;
 import org.hibernate.validator.constraints.Range;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
@@ -31,6 +33,7 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.constraints.Min;
+import java.util.ArrayList;
 import java.util.Map;
 
 /**
@@ -56,6 +59,9 @@ public class ClustersController {
         this.request = request;
     }
 
+    @Autowired
+    private RolesService rolesService;
+
     @ApiOperation(value = "Get the list of existing clusters, support paging, 
the default is 10 per page")
     @ApiResponses({
             @ApiResponse(code = 200, message = "ok"),
@@ -72,7 +78,17 @@ public class ClustersController {
             @Range(min = 1, max = 1000, message = "page_size is incorrect, 
should be greater than 0 and less than 1000.")
                     Integer pageSize) {
         String requestHost = environmentCacheService.getServiceUrl(request);
-        Map<String, Object> result = clusterService.getClustersList(
+        String token = request.getHeader("token");
+        Map<String, Object> result = Maps.newHashMap();
+        if (!rolesService.isSuperUser(token)) {
+            result.put("isPage", false);
+            result.put("total", 0);
+            result.put("data", new ArrayList());
+            result.put("pageNum", 0);
+            result.put("pageSize", 0);
+            return ResponseEntity.ok(result);
+        }
+        result = clusterService.getClustersList(
             pageNum, pageSize, requestHost, cluster -> {
                 String environment = request.getHeader("environment");
                 if (null == environment) {
diff --git 
a/src/main/java/org/apache/pulsar/manager/controller/EnvironmentsController.java
 
b/src/main/java/org/apache/pulsar/manager/controller/EnvironmentsController.java
index f5a40b7..76a5024 100644
--- 
a/src/main/java/org/apache/pulsar/manager/controller/EnvironmentsController.java
+++ 
b/src/main/java/org/apache/pulsar/manager/controller/EnvironmentsController.java
@@ -13,11 +13,19 @@
  */
 package org.apache.pulsar.manager.controller;
 
-import com.github.pagehelper.Page;
 import com.google.common.collect.Maps;
 import org.apache.pulsar.manager.entity.EnvironmentEntity;
 import org.apache.pulsar.manager.entity.EnvironmentsRepository;
+import org.apache.pulsar.manager.entity.RoleBindingEntity;
+import org.apache.pulsar.manager.entity.RoleBindingRepository;
+import org.apache.pulsar.manager.entity.RoleInfoEntity;
+import org.apache.pulsar.manager.entity.RolesRepository;
+import org.apache.pulsar.manager.entity.TenantEntity;
+import org.apache.pulsar.manager.entity.TenantsRepository;
+import org.apache.pulsar.manager.entity.UserInfoEntity;
+import org.apache.pulsar.manager.entity.UsersRepository;
 import org.apache.pulsar.manager.service.EnvironmentCacheService;
+import org.apache.pulsar.manager.service.RolesService;
 import org.apache.pulsar.manager.utils.HttpUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -25,6 +33,7 @@ import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.pulsar.manager.utils.ResourceType;
 import org.hibernate.validator.constraints.Range;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -36,7 +45,10 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.validation.constraints.Min;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
@@ -53,14 +65,38 @@ public class EnvironmentsController {
     private String pulsarJwtToken;
 
     private final EnvironmentsRepository environmentsRepository;
+
     private final EnvironmentCacheService environmentCacheService;
 
-    @Autowired
+    private final UsersRepository usersRepository;
+
+    private final TenantsRepository tenantsRepository;
+
+    private final RolesRepository rolesRepository;
+
+    private final RoleBindingRepository roleBindingRepository;
+
+    private final RolesService rolesService;
+
+    private final HttpServletRequest request;
+
     public EnvironmentsController(
+            HttpServletRequest request,
             EnvironmentsRepository environmentsRepository,
-            EnvironmentCacheService environmentCacheService) {
+            EnvironmentCacheService environmentCacheService,
+            UsersRepository usersRepository,
+            TenantsRepository tenantsRepository,
+            RolesRepository rolesRepository,
+            RoleBindingRepository roleBindingRepository,
+            RolesService rolesService) {
         this.environmentsRepository = environmentsRepository;
         this.environmentCacheService = environmentCacheService;
+        this.request = request;
+        this.usersRepository = usersRepository;
+        this.tenantsRepository = tenantsRepository;
+        this.rolesRepository = rolesRepository;
+        this.roleBindingRepository = roleBindingRepository;
+        this.rolesService = rolesService;
     }
 
     @ApiOperation(value = "Get the list of existing environments, support 
paging, the default is 10 per page")
@@ -78,10 +114,42 @@ public class EnvironmentsController {
             @RequestParam(name="page_size", defaultValue = "10")
             @Range(min = 1, max = 1000, message = "page_size is incorrect, 
should be greater than 0 and less than 1000.")
             Integer pageSize) {
-        Page<EnvironmentEntity> environmentEntityPage = 
environmentsRepository.getEnvironmentsList(pageNum, pageSize);
+        String token = request.getHeader("token");
         Map<String, Object> result = Maps.newHashMap();
-        result.put("total", environmentEntityPage.getTotal());
-        result.put("data", environmentEntityPage);
+        List<EnvironmentEntity> environmentEntities;
+        if (!rolesService.isSuperUser(token)) {
+            Optional<UserInfoEntity> userInfoEntityOptional = 
usersRepository.findByAccessToken(token);
+            // There is no need to check whether the user exists again; the 
user must exist.
+            UserInfoEntity userInfoEntity = userInfoEntityOptional.get();
+            long userId = userInfoEntity.getUserId();
+            List<RoleBindingEntity> roleBindingInfoEntities = 
roleBindingRepository.findByUserId(userId);
+            List<Long> roleIdList = new ArrayList<>();
+            List<String> environmentList = new ArrayList<>();
+            for (RoleBindingEntity roleInfoEntity : roleBindingInfoEntities) {
+                roleIdList.add(roleInfoEntity.getRoleId());
+            }
+            if (!roleIdList.isEmpty()) {
+                List<RoleInfoEntity> roleInfoEntities = 
rolesRepository.findAllRolesByMultiId(roleIdList);
+                List<Long> tenantsIdList = new ArrayList<>();
+                for (RoleInfoEntity roleInfoEntity : roleInfoEntities) {
+                    if 
(roleInfoEntity.getResourceType().equals(ResourceType.TENANTS.name())) {
+                        tenantsIdList.add(roleInfoEntity.getResourceId());
+                    }
+                }
+                if (!tenantsIdList.isEmpty()) {
+                    List<TenantEntity> tenantEntities = 
tenantsRepository.findByMultiId(tenantsIdList);
+                    for (TenantEntity tenantEntity : tenantEntities) {
+                        environmentList.add(tenantEntity.getEnvironmentName());
+                    }
+                }
+            }
+            environmentEntities = 
environmentsRepository.getAllEnvironments(environmentList);
+        } else {
+            environmentEntities = environmentsRepository.getAllEnvironments();
+        }
+
+        result.put("total", environmentEntities.size());
+        result.put("data", environmentEntities);
         return ResponseEntity.ok(result);
     }
 
@@ -93,9 +161,14 @@ public class EnvironmentsController {
     @RequestMapping(value = "/environments/environment", method =  
RequestMethod.PUT)
     public ResponseEntity<Map<String, Object>> addEnvironment(
             @RequestBody EnvironmentEntity environmentEntity) {
+        Map<String, Object> result = Maps.newHashMap();
+        String token = request.getHeader("token");
+        if (!rolesService.isSuperUser(token)) {
+            result.put("error", "User does not have permission to operate");
+            return ResponseEntity.ok(result);
+        }
         Optional<EnvironmentEntity> environmentEntityBrokerOptional = 
environmentsRepository
                 .findByBroker(environmentEntity.getBroker());
-        Map<String, Object> result = Maps.newHashMap();
         if (environmentEntityBrokerOptional.isPresent()) {
             result.put("error", "Broker is exist");
             return ResponseEntity.ok(result);
@@ -133,9 +206,14 @@ public class EnvironmentsController {
     })
     @RequestMapping(value = "/environments/environment", method =  
RequestMethod.POST)
     public ResponseEntity<Map<String, Object>> updateEnvironment(@RequestBody 
EnvironmentEntity environmentEntity) {
+        Map<String, Object> result = Maps.newHashMap();
+        String token = request.getHeader("token");
+        if (!rolesService.isSuperUser(token)) {
+            result.put("error", "User does not have permission to operate");
+            return ResponseEntity.ok(result);
+        }
         Optional<EnvironmentEntity> environmentEntityOptional = 
environmentsRepository
                 .findByName(environmentEntity.getName());
-        Map<String, Object> result = Maps.newHashMap();
         if (!environmentEntityOptional.isPresent()) {
             result.put("error", "Environment no exist");
             return ResponseEntity.ok(result);
@@ -163,9 +241,14 @@ public class EnvironmentsController {
     })
     @RequestMapping(value = "/environments/environment", method =  
RequestMethod.DELETE)
     public ResponseEntity<Map<String, Object>> deleteEnvironment(@RequestBody 
EnvironmentEntity environmentEntity) {
+        Map<String, Object> result = Maps.newHashMap();
+        String token = request.getHeader("token");
+        if (!rolesService.isSuperUser(token)) {
+            result.put("error", "User does not have permission to operate");
+            return ResponseEntity.ok(result);
+        }
         Optional<EnvironmentEntity> environmentEntityOptional = 
environmentsRepository
                 .findByName(environmentEntity.getName());
-        Map<String, Object> result = Maps.newHashMap();
         if (!environmentEntityOptional.isPresent()) {
             result.put("error", "Environment no exist");
             return ResponseEntity.ok(result);
diff --git 
a/src/main/java/org/apache/pulsar/manager/controller/LoginController.java 
b/src/main/java/org/apache/pulsar/manager/controller/LoginController.java
index f52e27d..4973a32 100644
--- a/src/main/java/org/apache/pulsar/manager/controller/LoginController.java
+++ b/src/main/java/org/apache/pulsar/manager/controller/LoginController.java
@@ -16,6 +16,10 @@ package org.apache.pulsar.manager.controller;
 import com.google.common.collect.Maps;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.pulsar.manager.entity.RoleBindingEntity;
+import org.apache.pulsar.manager.entity.RoleBindingRepository;
+import org.apache.pulsar.manager.entity.RoleInfoEntity;
+import org.apache.pulsar.manager.entity.RolesRepository;
 import org.apache.pulsar.manager.entity.UserInfoEntity;
 import org.apache.pulsar.manager.entity.UsersRepository;
 import org.apache.pulsar.manager.service.JwtService;
@@ -23,7 +27,6 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
-import org.apache.pulsar.manager.service.RolesService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpHeaders;
@@ -38,6 +41,8 @@ import 
org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
@@ -71,7 +76,10 @@ public class LoginController {
     private UsersRepository usersRepository;
 
     @Autowired
-    private RolesService rolesService;
+    private RolesRepository rolesRepository;
+
+    @Autowired
+    private RoleBindingRepository roleBindingRepository;
 
     @ApiOperation(value = "Login pulsar manager")
     @ApiResponses({
@@ -106,9 +114,22 @@ public class LoginController {
             headers.add("username", userAccount);
             headers.add("tenant", userAccount);
             jwtService.setToken(request.getSession().getId(), token);
-            // Create default role and tenant
-            rolesService.createDefaultRoleAndTenant(userAccount);
-
+            List<RoleBindingEntity> roleBindingEntities = 
roleBindingRepository.
+                    findByUserId(userInfoEntity.getUserId());
+            List<Long> roleIdList = new ArrayList<>();
+            for (RoleBindingEntity roleBindingEntity : roleBindingEntities) {
+                roleIdList.add(roleBindingEntity.getRoleId());
+            }
+            if (!roleIdList.isEmpty()) {
+                List<RoleInfoEntity> roleInfoEntities = 
rolesRepository.findAllRolesByMultiId(roleIdList);
+                for (RoleInfoEntity roleInfoEntity : roleInfoEntities) {
+                    if (roleInfoEntity.getFlag() == 0) {
+                        // Super users can access all types
+                        return new ResponseEntity<>(result, headers, 
HttpStatus.OK);
+                    }
+                }
+            }
+            headers.add("role", "admin");
             return new ResponseEntity<>(result, headers, HttpStatus.OK);
         }
         if (userAccount.equals(account) && userPassword.equals(password)) {
diff --git 
a/src/main/java/org/apache/pulsar/manager/controller/RoleBindingController.java 
b/src/main/java/org/apache/pulsar/manager/controller/RoleBindingController.java
index a0937c4..5fb477d 100644
--- 
a/src/main/java/org/apache/pulsar/manager/controller/RoleBindingController.java
+++ 
b/src/main/java/org/apache/pulsar/manager/controller/RoleBindingController.java
@@ -86,6 +86,12 @@ public class RoleBindingController {
                 RequestContextHolder.getRequestAttributes()).getRequest();
         String token = request.getHeader("token");
         String tenant = request.getHeader("tenant");
+        if (rolesService.isSuperUser(token)) {
+            List<Map<String, Object>> roleBindingList = 
roleBindingService.getAllRoleBindingList();
+            result.put("total", roleBindingList.size());
+            result.put("data", roleBindingList);
+            return ResponseEntity.ok(result);
+        }
         Map<String, String> validateResult = 
rolesService.validateCurrentTenant(token, tenant);
         if (validateResult.get("error") != null) {
             result.put("error", validateResult.get("error"));
diff --git 
a/src/main/java/org/apache/pulsar/manager/controller/RolesController.java 
b/src/main/java/org/apache/pulsar/manager/controller/RolesController.java
index ca5cef4..0f94ddb 100644
--- a/src/main/java/org/apache/pulsar/manager/controller/RolesController.java
+++ b/src/main/java/org/apache/pulsar/manager/controller/RolesController.java
@@ -27,7 +27,6 @@ import org.apache.pulsar.manager.entity.RolesRepository;
 import org.apache.pulsar.manager.service.RolesService;
 import org.apache.pulsar.manager.utils.ResourceType;
 import org.hibernate.validator.constraints.Range;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -36,8 +35,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.constraints.Min;
@@ -54,14 +51,24 @@ import java.util.Set;
 @Validated
 public class RolesController {
 
-    @Autowired
-    private RolesRepository rolesRepository;
+    private final RolesRepository rolesRepository;
 
-    @Autowired
-    private RolesService rolesService;
+    private final RolesService rolesService;
 
-    @Autowired
-    private NamespacesRepository namespacesRepository;
+    private final NamespacesRepository namespacesRepository;
+
+    private final HttpServletRequest request;
+
+    public RolesController(
+            RolesRepository rolesRepository,
+            RolesService rolesService,
+            NamespacesRepository namespacesRepository,
+            HttpServletRequest request) {
+        this.rolesRepository = rolesRepository;
+        this.rolesService = rolesService;
+        this.namespacesRepository = namespacesRepository;
+        this.request = request;
+    }
 
     @ApiOperation(value = "Get the list of existing roles, support paging, the 
default is 10 per page")
     @ApiResponses({
@@ -79,11 +86,15 @@ public class RolesController {
             @RequestParam(name = "page_size", defaultValue = "10")
             @Range(min = 1, max = 1000, message = "page_size is incorrect, 
should be greater than 0 and less than 1000.")
                     Integer pageSize) {
-        HttpServletRequest request = ((ServletRequestAttributes)
-                RequestContextHolder.getRequestAttributes()).getRequest();
         String token = request.getHeader("token");
         Map<String, Object> result = Maps.newHashMap();
         String tenant = request.getHeader("tenant");
+        if (rolesService.isSuperUser(token)) {
+            List<RoleInfoEntity> roleInfoEntities = 
rolesRepository.findAllRolesList();
+            result.put("total", roleInfoEntities.size());
+            result.put("data", roleInfoEntities);
+            return ResponseEntity.ok(result);
+        }
         Map<String, String> validateResult = 
rolesService.validateCurrentTenant(token, tenant);
         if (validateResult.get("error") != null) {
             result.put("error", validateResult.get("error"));
@@ -105,8 +116,6 @@ public class RolesController {
     @RequestMapping(value = "/roles/role", method = RequestMethod.PUT)
     public ResponseEntity<Map<String, Object>> addRole(
             @RequestBody RoleInfoEntity roleInfoEntity) {
-        HttpServletRequest request = ((ServletRequestAttributes)
-                RequestContextHolder.getRequestAttributes()).getRequest();
         String token = request.getHeader("token");
         Map<String, Object> result = Maps.newHashMap();
         String tenant = request.getHeader("tenant");
@@ -149,8 +158,6 @@ public class RolesController {
     @RequestMapping(value = "/roles/role", method = RequestMethod.POST)
     public ResponseEntity<Map<String, Object>> updateRole(@RequestBody 
RoleInfoEntity roleInfoEntity) {
         Map<String, Object> result = Maps.newHashMap();
-        HttpServletRequest request = ((ServletRequestAttributes)
-                RequestContextHolder.getRequestAttributes()).getRequest();
         String token = request.getHeader("token");
         String tenant = request.getHeader("tenant");
         Map<String, String> validateResult = 
rolesService.validateCurrentTenant(token, tenant);
@@ -192,8 +199,6 @@ public class RolesController {
     @RequestMapping(value = "/roles/role", method = RequestMethod.DELETE)
     public ResponseEntity<Map<String, Object>> deleteRole(@RequestBody 
RoleInfoEntity roleInfoEntity) {
         Map<String, Object> result = Maps.newHashMap();
-        HttpServletRequest request = ((ServletRequestAttributes)
-                RequestContextHolder.getRequestAttributes()).getRequest();
         String token = request.getHeader("token");
         String tenant = request.getHeader("tenant");
         Map<String, String> validateResult = 
rolesService.validateCurrentTenant(token, tenant);
@@ -240,8 +245,6 @@ public class RolesController {
     @RequestMapping(value = "/role/resource/{resourceType}", method = 
RequestMethod.GET)
     public ResponseEntity<Map<String, Object>> getResource(@PathVariable 
String resourceType) {
         Map<String, Object> result = Maps.newHashMap();
-        HttpServletRequest request = ((ServletRequestAttributes)
-                RequestContextHolder.getRequestAttributes()).getRequest();
         String token = request.getHeader("token");
         String tenant = request.getHeader("tenant");
         Map<String, String> validateResult = 
rolesService.validateCurrentTenant(token, tenant);
diff --git 
a/src/main/java/org/apache/pulsar/manager/controller/TenantsController.java 
b/src/main/java/org/apache/pulsar/manager/controller/TenantsController.java
index 9fa86d6..1319048 100644
--- a/src/main/java/org/apache/pulsar/manager/controller/TenantsController.java
+++ b/src/main/java/org/apache/pulsar/manager/controller/TenantsController.java
@@ -13,13 +13,24 @@
  */
 package org.apache.pulsar.manager.controller;
 
+import com.google.common.collect.Maps;
+import org.apache.pulsar.manager.entity.RoleBindingEntity;
+import org.apache.pulsar.manager.entity.RoleBindingRepository;
+import org.apache.pulsar.manager.entity.RoleInfoEntity;
+import org.apache.pulsar.manager.entity.RolesRepository;
+import org.apache.pulsar.manager.entity.TenantEntity;
+import org.apache.pulsar.manager.entity.TenantsRepository;
+import org.apache.pulsar.manager.entity.UserInfoEntity;
+import org.apache.pulsar.manager.entity.UsersRepository;
 import org.apache.pulsar.manager.service.EnvironmentCacheService;
+import org.apache.pulsar.manager.service.RolesService;
 import org.apache.pulsar.manager.service.TenantsService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
+import org.apache.pulsar.manager.utils.ResourceType;
 import org.hibernate.validator.constraints.Range;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
@@ -31,7 +42,10 @@ import 
org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.constraints.Min;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 /**
  * Tenant Query class.
@@ -43,17 +57,38 @@ import java.util.Map;
 public class TenantsController {
 
     private final TenantsService tenantsService;
+
     private final EnvironmentCacheService environmentCacheService;
+
     private final HttpServletRequest request;
 
-    @Autowired
+    private final UsersRepository usersRepository;
+
+    private final RoleBindingRepository roleBindingRepository;
+
+    private final RolesRepository rolesRepository;
+
+    private final RolesService rolesService;
+
+    private final TenantsRepository tenantsRepository;
+
     public TenantsController(
+            HttpServletRequest request,
             TenantsService tenantsService,
             EnvironmentCacheService environmentCacheService,
-            HttpServletRequest request) {
+            UsersRepository usersRepository,
+            RoleBindingRepository roleBindingRepository,
+            RolesRepository rolesRepository,
+            RolesService rolesService,
+            TenantsRepository tenantsRepository) {
+        this.request = request;
         this.tenantsService = tenantsService;
         this.environmentCacheService = environmentCacheService;
-        this.request = request;
+        this.usersRepository = usersRepository;
+        this.roleBindingRepository = roleBindingRepository;
+        this.rolesRepository = rolesRepository;
+        this.rolesService = rolesService;
+        this.tenantsRepository = tenantsRepository;
     }
 
     @ApiOperation(value = "Get the list of existing tenants, support paging, 
the default is 10 per page")
@@ -72,8 +107,41 @@ public class TenantsController {
         @RequestParam(name="page_size", defaultValue = "10")
         @Range(min = 1, max = 1000, message = "page_size is incorrect, should 
be greater than 0 and less than 1000.")
             Integer pageSize) {
+        String token = request.getHeader("token");
+        Map<String, Object> result = Maps.newHashMap();
+        if (!rolesService.isSuperUser(token)) {
+            List<TenantEntity> tenantEntities = null;
+            Optional<UserInfoEntity> userInfoEntityOptional = 
usersRepository.findByAccessToken(token);
+            // There is no need to check whether the user exists again; the 
user must exist.
+            UserInfoEntity userInfoEntity = userInfoEntityOptional.get();
+            long userId = userInfoEntity.getUserId();
+            List<RoleBindingEntity> roleBindingInfoEntities = 
roleBindingRepository.findByUserId(userId);
+            List<Long> roleIdList = new ArrayList<>();
+            for (RoleBindingEntity roleInfoEntity : roleBindingInfoEntities) {
+                roleIdList.add(roleInfoEntity.getRoleId());
+            }
+            if (!roleIdList.isEmpty()) {
+                List<RoleInfoEntity> roleInfoEntities = 
rolesRepository.findAllRolesByMultiId(roleIdList);
+                List<Long> tenantsIdList = new ArrayList<>();
+                for (RoleInfoEntity roleInfoEntity : roleInfoEntities) {
+                    tenantsIdList.add(roleInfoEntity.getResourceId());
+                }
+                if (!tenantsIdList.isEmpty()) {
+                    tenantEntities = 
tenantsRepository.findByMultiId(tenantsIdList);
+                }
+            }
+            if (tenantEntities != null) {
+                result.put("data", tenantEntities);
+                result.put("total", tenantEntities.size());
+                result.put("isPage", false);
+                return ResponseEntity.ok(result);
+            } else {
+                result.put("error", "Get tenant error");
+                return ResponseEntity.ok(result);
+            }
+        }
         String requestHost = environmentCacheService.getServiceUrl(request);
-        Map<String, Object> result = tenantsService.getTenantsList(pageNum, 
pageSize, requestHost);
+        result = tenantsService.getTenantsList(pageNum, pageSize, requestHost);
         return ResponseEntity.ok(result);
     }
 }
diff --git 
a/src/main/java/org/apache/pulsar/manager/controller/UsersController.java 
b/src/main/java/org/apache/pulsar/manager/controller/UsersController.java
index e740f16..df46f94 100644
--- a/src/main/java/org/apache/pulsar/manager/controller/UsersController.java
+++ b/src/main/java/org/apache/pulsar/manager/controller/UsersController.java
@@ -15,6 +15,7 @@ package org.apache.pulsar.manager.controller;
 
 import com.github.pagehelper.Page;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -23,22 +24,36 @@ import io.swagger.annotations.ApiResponses;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.validator.routines.EmailValidator;
+import org.apache.pulsar.manager.entity.RoleBindingEntity;
+import org.apache.pulsar.manager.entity.RoleBindingRepository;
+import org.apache.pulsar.manager.entity.RoleInfoEntity;
+import org.apache.pulsar.manager.entity.RolesRepository;
 import org.apache.pulsar.manager.entity.UserInfoEntity;
 import org.apache.pulsar.manager.entity.UsersRepository;
+import org.apache.pulsar.manager.service.RolesService;
 import org.apache.pulsar.manager.service.UsersService;
+import org.apache.pulsar.manager.utils.ResourceType;
+import org.apache.pulsar.manager.utils.ResourceVerbs;
 import org.hibernate.validator.constraints.Range;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 import javax.validation.constraints.Min;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 
 /**
  * Users management controller.
@@ -48,11 +63,39 @@ import java.util.Optional;
 @Api(description = "Functions under this class are available to super user.")
 public class UsersController {
 
-    @Autowired
-    private UsersRepository usersRepository;
+    @Value("${user.management.enable}")
+    private boolean userManagementEnable;
+
+    @Value("${pulsar-manager.account}")
+    private String account;
+
+    private final UsersRepository usersRepository;
+
+    private final UsersService usersService;
+
+    private final RolesRepository rolesRepository;
+
+    private final RoleBindingRepository roleBindingRepository;
+
+    private final RolesService rolesService;
+
+    private final HttpServletRequest request;
 
     @Autowired
-    private UsersService usersService;
+    public UsersController(
+            UsersRepository usersRepository,
+            UsersService usersService,
+            RolesRepository rolesRepository,
+            RoleBindingRepository roleBindingRepository,
+            RolesService rolesService,
+            HttpServletRequest request) {
+        this.usersRepository = usersRepository;
+        this.usersService = usersService;
+        this.rolesRepository = rolesRepository;
+        this.roleBindingRepository = roleBindingRepository;
+        this.rolesService = rolesService;
+        this.request = request;
+    }
 
     @ApiOperation(value = "Get users list")
     @ApiResponses({
@@ -99,6 +142,13 @@ public class UsersController {
         }
         
userInfoEntity.setPassword(DigestUtils.sha256Hex(userInfoEntity.getPassword()));
         usersRepository.save(userInfoEntity);
+        // Create default role and tenant
+        Map<String, String> defaultRoleCreate = 
rolesService.createDefaultRoleAndTenant(
+                userInfoEntity.getName(), request.getHeader("environment"));
+        if (defaultRoleCreate.get("error") != null) {
+            result.put("error", defaultRoleCreate.get("error"));
+            return ResponseEntity.ok(result);
+        }
         result.put("message", "Create user success");
         return ResponseEntity.ok(result);
     }
@@ -151,4 +201,101 @@ public class UsersController {
         result.put("message", "Delete a user success");
         return ResponseEntity.ok(result);
     }
+
+    @ApiOperation(value = "Get user info")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "ok"),
+            @ApiResponse(code = 404, message = "Not found"),
+            @ApiResponse(code = 500, message = "Internal server error")
+    })
+    @RequestMapping(value = "/users/userInfo", method = RequestMethod.GET)
+    public ResponseEntity<Map<String, Object>> getUserInfo() {
+        Map<String, Object> result = Maps.newHashMap();
+        Set<String> roles  = Sets.newHashSet();
+        if (userManagementEnable) {
+            HttpServletRequest request = ((ServletRequestAttributes) 
RequestContextHolder.getRequestAttributes()).getRequest();
+            String token = request.getHeader("token");
+            Optional<UserInfoEntity> userInfoEntityOptional = 
usersRepository.findByAccessToken(token);
+            if (!userInfoEntityOptional.isPresent()) {
+                result.put("error", "User is no exist");
+                return ResponseEntity.ok(result);
+            }
+            UserInfoEntity userInfoEntity = userInfoEntityOptional.get();
+            List<RoleBindingEntity> roleBindingEntities = 
roleBindingRepository.findByUserId(userInfoEntity.getUserId());
+            List<Long> roleIdList = new ArrayList<>();
+            for (RoleBindingEntity roleBindingEntity : roleBindingEntities) {
+                roleIdList.add(roleBindingEntity.getRoleId());
+            }
+            List<RoleInfoEntity> roleInfoEntities = 
rolesRepository.findAllRolesByMultiId(roleIdList);
+            for (RoleInfoEntity roleInfoEntity : roleInfoEntities) {
+                if (roleInfoEntity.getFlag() == 0) {
+                    result.put("message", "Get user info success");
+                    result.put("userName", userInfoEntity.getName());
+                    result.put("description", userInfoEntity.getDescription());
+                    roles.add("super");
+                    result.put("roles", roles);
+                    return ResponseEntity.ok(result);
+                }
+            }
+            result.put("message", "Get user info success");
+            result.put("userName", userInfoEntity.getName());
+            result.put("description", userInfoEntity.getDescription());
+            roles.add("admin");
+            result.put("roles", roles);
+            return ResponseEntity.ok(result);
+        }
+        result.put("message", "Get user info success");
+        result.put("description", "This is super account");
+        result.put("userName", account);
+        roles.add("super");
+        result.put("roles", roles);
+        return ResponseEntity.ok(result);
+    }
+
+    @ApiOperation(value = "Add a super user, only used when the platform is 
initialized for the first time.")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "ok"),
+            @ApiResponse(code = 404, message = "Not found"),
+            @ApiResponse(code = 500, message = "Internal server error")
+    })
+    @RequestMapping(value = "/users/superuser", method = RequestMethod.PUT)
+    public ResponseEntity<Map<String, Object>> createSuperUser(@RequestBody 
UserInfoEntity userInfoEntity) {
+        Map<String, Object> result = Maps.newHashMap();
+        // 0 is super role
+        Optional<RoleInfoEntity> roleInfoEntityOptional = 
rolesRepository.findByRoleFlag(0);
+        if (roleInfoEntityOptional.isPresent()) {
+            result.put("error", "Super user role is exist, this interface is 
no longer available");
+            return ResponseEntity.ok(result);
+        }
+        Map<String, String> userValidateResult = 
usersService.validateUserInfo(userInfoEntity);
+        if (userValidateResult.get("error") != null) {
+            result.put("error", userValidateResult.get("error"));
+            return ResponseEntity.ok(result);
+        }
+        if (StringUtils.isBlank(userInfoEntity.getPassword())) {
+            result.put("error", "Please provider password");
+            return ResponseEntity.ok(result);
+        }
+
+        RoleInfoEntity roleInfoEntity = new RoleInfoEntity();
+        roleInfoEntity.setRoleName(userInfoEntity.getName());
+        roleInfoEntity.setResourceId(0);
+        roleInfoEntity.setRoleSource(roleInfoEntity.getRoleName());
+        roleInfoEntity.setResourceType(ResourceType.ALL.name());
+        roleInfoEntity.setResourceName("superuser");
+        roleInfoEntity.setResourceVerbs(ResourceVerbs.SUPER_USER.name());
+        roleInfoEntity.setFlag(0);
+        roleInfoEntity.setDescription("This is super role");
+        long roleId = rolesRepository.save(roleInfoEntity);
+        
userInfoEntity.setPassword(DigestUtils.sha256Hex(userInfoEntity.getPassword()));
+        long userId = usersRepository.save(userInfoEntity);
+        RoleBindingEntity roleBindingEntity = new RoleBindingEntity();
+        roleBindingEntity.setDescription("This is super role binding");
+        roleBindingEntity.setName("super_user_role_binding");
+        roleBindingEntity.setRoleId(roleId);
+        roleBindingEntity.setUserId(userId);
+        roleBindingRepository.save(roleBindingEntity);
+        result.put("message", "Add super user success, please login");
+        return ResponseEntity.ok(result);
+    }
 }
diff --git 
a/src/main/java/org/apache/pulsar/manager/dao/EnvironmentsRepositoryImpl.java 
b/src/main/java/org/apache/pulsar/manager/dao/EnvironmentsRepositoryImpl.java
index a0b570a..0e4d943 100644
--- 
a/src/main/java/org/apache/pulsar/manager/dao/EnvironmentsRepositoryImpl.java
+++ 
b/src/main/java/org/apache/pulsar/manager/dao/EnvironmentsRepositoryImpl.java
@@ -64,6 +64,11 @@ public class EnvironmentsRepositoryImpl implements 
EnvironmentsRepository {
     }
 
     @Override
+    public List<EnvironmentEntity> getAllEnvironments(List<String> 
envonmentNameList) {
+        return 
environmentsMapper.findEnvironmentsListByMultiName(envonmentNameList);
+    }
+
+    @Override
     public void remove(String name) {
         environmentsMapper.delete(name);
     }
diff --git 
a/src/main/java/org/apache/pulsar/manager/dao/RoleBindingRepositoryImpl.java 
b/src/main/java/org/apache/pulsar/manager/dao/RoleBindingRepositoryImpl.java
index d1f64cd..f635f2f 100644
--- a/src/main/java/org/apache/pulsar/manager/dao/RoleBindingRepositoryImpl.java
+++ b/src/main/java/org/apache/pulsar/manager/dao/RoleBindingRepositoryImpl.java
@@ -63,6 +63,11 @@ public class RoleBindingRepositoryImpl implements 
RoleBindingRepository {
     }
 
     @Override
+    public List<RoleBindingEntity> findAllRoleBindingList() {
+        return this.roleBindingMapper.findAllRoleBindinglist();
+    }
+
+    @Override
     public List<RoleBindingEntity> findByMultiRoleId(List<Long> roleIdList) {
         return this.roleBindingMapper.findByMultiRoleId(roleIdList);
     }
diff --git 
a/src/main/java/org/apache/pulsar/manager/dao/RolesRepositoryImpl.java 
b/src/main/java/org/apache/pulsar/manager/dao/RolesRepositoryImpl.java
index 5071ea4..497afdc 100644
--- a/src/main/java/org/apache/pulsar/manager/dao/RolesRepositoryImpl.java
+++ b/src/main/java/org/apache/pulsar/manager/dao/RolesRepositoryImpl.java
@@ -46,12 +46,22 @@ public class RolesRepositoryImpl implements RolesRepository 
{
     }
 
     @Override
+    public Optional<RoleInfoEntity> findByRoleFlag(int flag) {
+        return Optional.ofNullable(this.rolesMapper.findByRoleFlag(flag));
+    }
+
+    @Override
     public Page<RoleInfoEntity> findRolesList(Integer pageNum, Integer 
pageSize) {
         PageHelper.startPage(pageNum, pageSize);
         return this.rolesMapper.findRoleList();
     }
 
     @Override
+    public List<RoleInfoEntity> findAllRolesList() {
+        return this.rolesMapper.findAllRoleList();
+    }
+
+    @Override
     public List<RoleInfoEntity> findRolesListByRoleSource(String roleSource) {
         return this.rolesMapper.findRoleListByRoleSource(roleSource);
     }
diff --git 
a/src/main/java/org/apache/pulsar/manager/entity/EnvironmentsRepository.java 
b/src/main/java/org/apache/pulsar/manager/entity/EnvironmentsRepository.java
index 7e65fd4..3f9a082 100644
--- a/src/main/java/org/apache/pulsar/manager/entity/EnvironmentsRepository.java
+++ b/src/main/java/org/apache/pulsar/manager/entity/EnvironmentsRepository.java
@@ -32,6 +32,8 @@ public interface EnvironmentsRepository {
 
     List<EnvironmentEntity> getAllEnvironments();
 
+    List<EnvironmentEntity> getAllEnvironments(List<String> envonmentNameList);
+
     void remove(String name);
 
     void update(EnvironmentEntity environmentEntity);
diff --git 
a/src/main/java/org/apache/pulsar/manager/entity/RoleBindingRepository.java 
b/src/main/java/org/apache/pulsar/manager/entity/RoleBindingRepository.java
index c541cbf..38a44db 100644
--- a/src/main/java/org/apache/pulsar/manager/entity/RoleBindingRepository.java
+++ b/src/main/java/org/apache/pulsar/manager/entity/RoleBindingRepository.java
@@ -67,6 +67,12 @@ public interface RoleBindingRepository {
     Page<RoleBindingEntity> getRoleBindingList(Integer pageNum, Integer 
pageSize);
 
     /**
+     * Get all role binding list.
+     * @return A list of RoleBindingEntity
+     */
+    List<RoleBindingEntity> findAllRoleBindingList();
+
+    /**
      * Update a role binding information
      * @param roleBindingEntity RoleInfoEntity
      */
diff --git 
a/src/main/java/org/apache/pulsar/manager/entity/RolesRepository.java 
b/src/main/java/org/apache/pulsar/manager/entity/RolesRepository.java
index e14c068..ce14ddf 100644
--- a/src/main/java/org/apache/pulsar/manager/entity/RolesRepository.java
+++ b/src/main/java/org/apache/pulsar/manager/entity/RolesRepository.java
@@ -36,6 +36,12 @@ public interface RolesRepository {
      */
     Optional<RoleInfoEntity> findByRoleName(String roleName, String 
roleSource);
 
+    /**
+     * Get a role information by role flag
+     * @param flag The role flag
+     * @return RoleInfoEntity
+     */
+    Optional<RoleInfoEntity> findByRoleFlag(int flag);
 
     /**
      * Get role list, support paging.
@@ -46,6 +52,12 @@ public interface RolesRepository {
     Page<RoleInfoEntity> findRolesList(Integer pageNum, Integer pageSize);
 
     /**
+     * Get all role list
+     * @return A list of RoleInfoEntity.
+     */
+    List<RoleInfoEntity> findAllRolesList();
+
+    /**
      * Get role list.
      * @param roleSource Role source, name of tenant
      * @return A list of RoleInfoEntity.
@@ -62,7 +74,7 @@ public interface RolesRepository {
     Page<RoleInfoEntity> findRolesMultiId(Integer pageNum, Integer pageSize, 
List<Long> idList);
 
     /**
-     * Get all role list by role id, support paging.
+     * Get all role list by role id
      * @param idList a list of role id
      * @return A list of RoleInfoEntity.
      */
diff --git a/src/main/java/org/apache/pulsar/manager/entity/TenantEntity.java 
b/src/main/java/org/apache/pulsar/manager/entity/TenantEntity.java
index 140be43..bb3e50f 100644
--- a/src/main/java/org/apache/pulsar/manager/entity/TenantEntity.java
+++ b/src/main/java/org/apache/pulsar/manager/entity/TenantEntity.java
@@ -40,4 +40,7 @@ public class TenantEntity {
     private String adminRoles;
     @SerializedName("allowed_clusters")
     private String allowedClusters;
+
+    @SerializedName("environment_name")
+    private String environmentName;
 }
\ No newline at end of file
diff --git 
a/src/main/java/org/apache/pulsar/manager/interceptor/AdminHandlerInterceptor.java
 
b/src/main/java/org/apache/pulsar/manager/interceptor/AdminHandlerInterceptor.java
index e0e19f0..f59066c 100644
--- 
a/src/main/java/org/apache/pulsar/manager/interceptor/AdminHandlerInterceptor.java
+++ 
b/src/main/java/org/apache/pulsar/manager/interceptor/AdminHandlerInterceptor.java
@@ -21,10 +21,13 @@ import 
org.apache.pulsar.manager.entity.EnvironmentsRepository;
 import org.apache.pulsar.manager.entity.UserInfoEntity;
 import org.apache.pulsar.manager.entity.UsersRepository;
 import org.apache.pulsar.manager.service.JwtService;
+import org.apache.pulsar.manager.service.PulsarEvent;
+import org.apache.pulsar.manager.service.RolesService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
@@ -52,33 +55,19 @@ public class AdminHandlerInterceptor extends 
HandlerInterceptorAdapter {
     @Value("${user.management.enable}")
     private boolean userManagementEnable;
 
+    @Autowired
+    private RolesService rolesService;
+
+    @Autowired
+    private PulsarEvent pulsarEvent;
+
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse 
response, Object handler) throws Exception {
         String token = request.getHeader("token");
         String saveToken = jwtService.getToken(request.getSession().getId());
         Map<String, Object> map = Maps.newHashMap();
         Gson gson = new Gson();
-        if (saveToken == null ) {
-            // Get token from database
-            String username = request.getHeader("username");
-            Optional<UserInfoEntity> userInfoEntityOptional = 
usersRepository.findByUserName(username);
-            if (!userInfoEntityOptional.isPresent()) {
-                map.put("message", "Please login.");
-                response.setStatus(401);
-                response.getWriter().append(gson.toJson(map));
-                return false;
-            }
-            UserInfoEntity userInfoEntity = userInfoEntityOptional.get();
-            if (StringUtils.isBlank(userInfoEntity.getAccessToken())) {
-                map.put("message", "The user token no find, please login");
-                response.setStatus(401);
-                response.getWriter().append(gson.toJson(map));
-                return false;
-            }
-            jwtService.setToken(request.getSession().getId(), 
userInfoEntity.getAccessToken());
-            saveToken = jwtService.getToken(request.getSession().getId());
-        }
-        if (token == null && !token.equals(saveToken)) {
+        if (token == null || !token.equals(saveToken)) {
             map.put("message", "Please login.");
             response.setStatus(401);
             response.getWriter().append(gson.toJson(map));
@@ -101,13 +90,44 @@ public class AdminHandlerInterceptor extends 
HandlerInterceptorAdapter {
                 return false;
             }
         }
-        String environment = request.getHeader("environment");
-        Optional<EnvironmentEntity> environmentEntityOptional = 
environmentsRepository.findByName(environment);
-        if 
(!request.getRequestURI().startsWith("/pulsar-manager/environments") && 
!environmentEntityOptional.isPresent()) {
-            map.put("message", "Currently there is no active environment, 
please set one");
-            response.setStatus(400);
-            response.getWriter().append(gson.toJson(map));
-            return false;
+        String requestUri = request.getRequestURI();
+        if (!requestUri.equals("/pulsar-manager/users/userInfo")) {
+            String environment = request.getHeader("environment");
+            Optional<EnvironmentEntity> environmentEntityOptional = 
environmentsRepository.findByName(environment);
+            if 
(!request.getRequestURI().startsWith("/pulsar-manager/environments") && 
!environmentEntityOptional.isPresent()) {
+                map.put("message", "Currently there is no active environment, 
please set one");
+                response.setStatus(400);
+                response.getWriter().append(gson.toJson(map));
+                return false;
+            }
+        }
+        if (!rolesService.isSuperUser(token)) {
+            if (requestUri.startsWith("/admin/v2/clusters")
+                    || requestUri.startsWith("/admin/v2/brokers")) {
+                map.put("message", "This user no permissions for this 
resource");
+                response.setStatus(401);
+                response.getWriter().append(gson.toJson(map));
+                return false;
+            }
+            if (requestUri.startsWith("/admin/v2/tenants")) {
+                if (request.getMethod() != "GET") {
+                    map.put("message", "This user no permissions for this 
resource");
+                    response.setStatus(401);
+                    response.getWriter().append(gson.toJson(map));
+                    return false;
+                }
+            }
+            if (requestUri.startsWith("/pulsar-manager/admin/v2/namespaces")
+                    || 
requestUri.startsWith("/pulsar-manager/admin/v2/persistent")
+                    || 
requestUri.startsWith("/pulsar-manager/admin/v2/non-persistent")) {
+                Map<String, String> result = 
pulsarEvent.validateTenantPermission(requestUri, token);
+                if (result.get("error") != null) {
+                    map.put("message", result.get("error"));
+                    response.setStatus(401);
+                    response.getWriter().append(gson.toJson(map));
+                    return false;
+                }
+            }
         }
         return true;
     }
diff --git 
a/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java 
b/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
index c79f4b8..c4d96b7 100644
--- a/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
+++ b/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
@@ -29,6 +29,7 @@ public class WebAppConfigurer implements WebMvcConfigurer {
     public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(adminHandlerInterceptor).addPathPatterns("/**")
                 .excludePathPatterns("/pulsar-manager/login")
+                .excludePathPatterns("/pulsar-manager/users/superuser")
                 .excludePathPatterns("/pulsar-manager/third-party-login/**");
     }
 }
diff --git 
a/src/main/java/org/apache/pulsar/manager/mapper/EnvironmentsMapper.java 
b/src/main/java/org/apache/pulsar/manager/mapper/EnvironmentsMapper.java
index 77abd91..74fb21b 100644
--- a/src/main/java/org/apache/pulsar/manager/mapper/EnvironmentsMapper.java
+++ b/src/main/java/org/apache/pulsar/manager/mapper/EnvironmentsMapper.java
@@ -34,6 +34,12 @@ public interface EnvironmentsMapper {
     @Select("SELECT name,broker FROM environments")
     Page<EnvironmentEntity> findEnvironmentsList();
 
+    @Select({"<script>",
+            "SELECT name,broker FROM environments",
+            "WHERE name IN <foreach collection='nameList' item='name' open='(' 
separator=',' close=')'> #{name} </foreach>" +
+                    "</script>"})
+    Page<EnvironmentEntity> findEnvironmentsListByMultiName(@Param("nameList") 
List<String> nameList);
+
     @Select("SELECT name,broker FROM environments")
     List<EnvironmentEntity> getAllEnvironments();
 
diff --git 
a/src/main/java/org/apache/pulsar/manager/mapper/RoleBindingMapper.java 
b/src/main/java/org/apache/pulsar/manager/mapper/RoleBindingMapper.java
index 728bec1..82cbf2f 100644
--- a/src/main/java/org/apache/pulsar/manager/mapper/RoleBindingMapper.java
+++ b/src/main/java/org/apache/pulsar/manager/mapper/RoleBindingMapper.java
@@ -58,6 +58,10 @@ public interface RoleBindingMapper {
             "FROM role_binding")
     Page<RoleBindingEntity> findRoleBindinglist();
 
+    @Select("SELECT name, role_binding_id as roleBindingId, description, 
user_id as userId, role_id as roleId " +
+            "FROM role_binding")
+    List<RoleBindingEntity> findAllRoleBindinglist();
+
     @Update("UPDATE role_binding " +
             "SET description = #{description}, name = #{name}, 
role_id=#{roleId}, user_id=#{userId} " +
             "Where role_binding_id=#{roleBindingId}")
diff --git a/src/main/java/org/apache/pulsar/manager/mapper/RolesMapper.java 
b/src/main/java/org/apache/pulsar/manager/mapper/RolesMapper.java
index 95342b6..d2e8d87 100644
--- a/src/main/java/org/apache/pulsar/manager/mapper/RolesMapper.java
+++ b/src/main/java/org/apache/pulsar/manager/mapper/RolesMapper.java
@@ -42,6 +42,13 @@ public interface RolesMapper {
             "WHERE role_name = #{roleName} and role_source = #{roleSource}")
     RoleInfoEntity findByRoleName(@Param("roleName") String roleName, 
@Param("roleSource") String roleSource);
 
+    @Select("SELECT role_id AS roleId, role_name AS roleName, description, 
resource_type AS resourceType," +
+            "resource_name AS resourceName, resource_verbs AS resourceVerbs, 
resource_id as resourceId," +
+            "role_source AS roleSource, flag " +
+            "FROM roles " +
+            "WHERE flag=#{flag} limit 1")
+    RoleInfoEntity findByRoleFlag(@Param("flag") int flag);
+
     @Select("SELECT role_name AS roleName, role_id AS roleId, description, 
resource_type AS resourceType," +
             "resource_name AS resourceName, resource_verbs AS resourceVerbs, 
resource_id as resourceId," +
             "role_source AS roleSource, flag FROM roles")
@@ -49,6 +56,11 @@ public interface RolesMapper {
 
     @Select("SELECT role_name AS roleName, role_id AS roleId, description, 
resource_type AS resourceType," +
             "resource_name AS resourceName, resource_verbs AS resourceVerbs, 
resource_id as resourceId," +
+            "role_source AS roleSource, flag FROM roles")
+    List<RoleInfoEntity> findAllRoleList();
+
+    @Select("SELECT role_name AS roleName, role_id AS roleId, description, 
resource_type AS resourceType," +
+            "resource_name AS resourceName, resource_verbs AS resourceVerbs, 
resource_id as resourceId," +
             "role_source AS roleSource, flag FROM roles WHERE 
role_source=#{roleSource}")
     List<RoleInfoEntity> findRoleListByRoleSource(String roleSource);
 
diff --git a/src/main/java/org/apache/pulsar/manager/mapper/TenantsMapper.java 
b/src/main/java/org/apache/pulsar/manager/mapper/TenantsMapper.java
index 539de32..37fc2d1 100644
--- a/src/main/java/org/apache/pulsar/manager/mapper/TenantsMapper.java
+++ b/src/main/java/org/apache/pulsar/manager/mapper/TenantsMapper.java
@@ -29,33 +29,38 @@ import java.util.List;
 @Mapper
 public interface TenantsMapper {
 
-    @Insert("INSERT INTO tenants (admin_roles, allowed_clusters, tenant) " +
-            "VALUES (#{adminRoles}, #{allowedClusters}, #{tenant})")
+    @Insert("INSERT INTO tenants (admin_roles, allowed_clusters, tenant, 
environment_name) " +
+            "VALUES (#{adminRoles}, #{allowedClusters}, #{tenant}, 
#{environmentName})")
     @Options(useGeneratedKeys=true, keyProperty="tenantId", 
keyColumn="tenant_id")
     long insert(TenantEntity tenantEntity);
 
 
-    @Select("SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters " +
+    @Select("SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters," +
+            "environment_name as environmentName " +
             "FROM tenants WHERE tenant = #{tenant}")
     TenantEntity findByName(String tenant);
 
-    @Select("SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters " +
+    @Select("SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters," +
+            "environment_name as environmentName " +
             "FROM tenants WHERE tenant_id = #{tenantId}")
     TenantEntity findByTenantId(long tenantId);
 
-    @Select("SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters " +
+    @Select("SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters," +
+            "environment_name as environmentName  " +
             "FROM tenants")
     Page<TenantEntity> getTenantsList();
 
     @Select({"<script>",
-            "SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters" +
+            "SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters," +
+                    "environment_name as environmentName " +
                     " FROM tenants ",
             "WHERE tenant_id IN <foreach collection='tenantIdList' 
item='tenantId' open='(' separator=',' close=')'> #{tenantId} </foreach>" +
                     "</script>"})
     Page<TenantEntity> findByMultiId(@Param("tenantIdList") List<Long> 
tenantIdList);
 
     @Select({"<script>",
-            "SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters" +
+            "SELECT tenant, tenant_id as tenantId, admin_roles as 
adminRoles,allowed_clusters as allowedClusters," +
+                    "environment_name as environmentName " +
                     " FROM tenants ",
             "WHERE tenant_id IN <foreach collection='tenantIdList' 
item='tenantId' open='(' separator=',' close=')'> #{tenantId} </foreach>" +
                     "</script>"})
diff --git a/src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java 
b/src/main/java/org/apache/pulsar/manager/service/PermissionsService.java
similarity index 80%
copy from src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java
copy to src/main/java/org/apache/pulsar/manager/service/PermissionsService.java
index 595c399..cf7f979 100644
--- a/src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java
+++ b/src/main/java/org/apache/pulsar/manager/service/PermissionsService.java
@@ -13,10 +13,7 @@
  */
 package org.apache.pulsar.manager.service;
 
-import javax.servlet.http.HttpServletRequest;
-
-public interface PulsarEvent {
-
-    void parsePulsarEvent(String path, HttpServletRequest httpRequest);
+public interface PermissionsService {
 
+    boolean hasPermissions(String path);
 }
diff --git a/src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java 
b/src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java
index 595c399..93cbf2f 100644
--- a/src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java
+++ b/src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java
@@ -14,9 +14,13 @@
 package org.apache.pulsar.manager.service;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
 
 public interface PulsarEvent {
 
     void parsePulsarEvent(String path, HttpServletRequest httpRequest);
 
+    Map<String, String> validateTenantPermission(String path, String token);
+
+    boolean validateRoutePermission(String path, String token);
 }
diff --git 
a/src/main/java/org/apache/pulsar/manager/service/RoleBindingService.java 
b/src/main/java/org/apache/pulsar/manager/service/RoleBindingService.java
index 60d7645..9e5766e 100644
--- a/src/main/java/org/apache/pulsar/manager/service/RoleBindingService.java
+++ b/src/main/java/org/apache/pulsar/manager/service/RoleBindingService.java
@@ -25,4 +25,6 @@ public interface RoleBindingService {
     Map<String, Object> validateCreateRoleBinding(String token, String tenant, 
String roleName, String userName);
 
     List<Map<String, Object>> getRoleBindingList(String token, String tenant);
+
+    List<Map<String, Object>> getAllRoleBindingList();
 }
diff --git a/src/main/java/org/apache/pulsar/manager/service/RolesService.java 
b/src/main/java/org/apache/pulsar/manager/service/RolesService.java
index 55ee61c..6b430af 100644
--- a/src/main/java/org/apache/pulsar/manager/service/RolesService.java
+++ b/src/main/java/org/apache/pulsar/manager/service/RolesService.java
@@ -22,9 +22,11 @@ public interface RolesService {
 
     Map<String, String> validateRoleInfoEntity(RoleInfoEntity roleInfoEntity);
 
-    void createDefaultRoleAndTenant(String tenant);
+    Map<String, String> createDefaultRoleAndTenant(String tenant, String 
environment);
 
     Set<String> getResourceVerbs(String resourceVerbs);
 
     Map<String, String> validateCurrentTenant(String token, String tenant);
+
+    boolean isSuperUser(String token);
 }
diff --git a/src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java 
b/src/main/java/org/apache/pulsar/manager/service/impl/PermissionsServiceImpl.java
similarity index 69%
copy from src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java
copy to 
src/main/java/org/apache/pulsar/manager/service/impl/PermissionsServiceImpl.java
index 595c399..6733783 100644
--- a/src/main/java/org/apache/pulsar/manager/service/PulsarEvent.java
+++ 
b/src/main/java/org/apache/pulsar/manager/service/impl/PermissionsServiceImpl.java
@@ -11,12 +11,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.pulsar.manager.service;
+package org.apache.pulsar.manager.service.impl;
 
-import javax.servlet.http.HttpServletRequest;
+import org.apache.pulsar.manager.service.PermissionsService;
 
-public interface PulsarEvent {
+public class PermissionsServiceImpl implements PermissionsService {
 
-    void parsePulsarEvent(String path, HttpServletRequest httpRequest);
+    public boolean hasPermissions(String path) {
+        return false;
+    }
 
 }
diff --git 
a/src/main/java/org/apache/pulsar/manager/service/impl/PulsarEventImpl.java 
b/src/main/java/org/apache/pulsar/manager/service/impl/PulsarEventImpl.java
index 2042e66..b1b6a4d 100644
--- a/src/main/java/org/apache/pulsar/manager/service/impl/PulsarEventImpl.java
+++ b/src/main/java/org/apache/pulsar/manager/service/impl/PulsarEventImpl.java
@@ -13,13 +13,16 @@
  */
 package org.apache.pulsar.manager.service.impl;
 
+import com.google.common.collect.Maps;
 import org.apache.pulsar.manager.entity.NamespaceEntity;
 import org.apache.pulsar.manager.entity.NamespacesRepository;
 import org.apache.pulsar.manager.service.PulsarEvent;
+import org.apache.pulsar.manager.service.RolesService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
 
 @Service
 public class PulsarEventImpl implements PulsarEvent {
@@ -30,8 +33,31 @@ public class PulsarEventImpl implements PulsarEvent {
 
     private static final String HTTP_DELETE = "DELETE";
 
+    private static final String TENANTS_PREFIX = "/admin/v2/tenants/";
+
+    private static final String CLUSTERS_PREFIX = "/admin/v2/clusters";
+
+    private static final String BROKERS_PREFIX = "/admin/v2/brokers";
+
+    private static final String BROKERS_STATS_PREFIX = 
"/admin/v2/broker-stats";
+
+    private static final String RESOURCES_QUOTAS_PREFIX = 
"/admin/v2/resource-quotas";
+
     private static final String NAMESPACES_PREFIX = "/admin/v2/namespaces";
 
+    private static final String PULSAR_MANAGER_NAMESPACES_PREFIX = 
"/pulsar-manager/admin/v2/namespaces";
+
+    private static final String PERSISTENT_TOPIC_PREFIX = 
"/admin/v2/persistent";
+
+    private static final String NON_PERSISTENT_TOPIC_PREFIX = 
"/admin/v2/non-persistent";
+
+    private static final String PULSAR_MANAGER_TOPIC_PREFIX = 
"/pulsar-manager/admin/v2/topics";
+
+    private static final String PULSAR_MANAGER_PREFIX = "/pulsar-manager";
+
+    @Autowired
+    private RolesService rolesService;
+
     @Autowired
     private NamespacesRepository namespacesRepository;
 
@@ -42,16 +68,88 @@ public class PulsarEventImpl implements PulsarEvent {
         return false;
     }
 
+    private boolean isNamespace(String path) {
+        if (path.startsWith(NAMESPACES_PREFIX) || 
path.startsWith(PULSAR_MANAGER_NAMESPACES_PREFIX)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isTopic(String path) {
+        if (path.startsWith(PERSISTENT_TOPIC_PREFIX)
+                || path.startsWith(NON_PERSISTENT_TOPIC_PREFIX)
+                || path.startsWith(PULSAR_MANAGER_TOPIC_PREFIX)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isTenant(String path) {
+        if (path.startsWith(TENANTS_PREFIX)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isCluster(String path) {
+        if (path.startsWith(CLUSTERS_PREFIX)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isBroker(String path) {
+        if (path.startsWith(BROKERS_PREFIX)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isBrokerStats(String path) {
+        if (path.startsWith(BROKERS_STATS_PREFIX)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isResourceQuota(String path) {
+        if (path.startsWith(RESOURCES_QUOTAS_PREFIX)) {
+            return true;
+        }
+        return false;
+    }
+
+    public boolean validateRoutePermission(String path, String token) {
+        if (isCluster(path) || isBroker(path) || isBrokerStats(path) || 
isResourceQuota(path)) {
+            if (rolesService.isSuperUser(token)) {
+                return true;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    public Map<String, String> validateTenantPermission(String path, String 
token) {
+        Map<String, String> result = Maps.newHashMap();
+        if (isTenant(path) || isNamespace(path) || isTopic(path)) {
+            String[] pathList = path.split(SEPARATOR);
+            String tenant;
+            if (path.startsWith(PULSAR_MANAGER_PREFIX)) {
+                tenant = pathList[5];
+            } else {
+                tenant = pathList[4];
+            }
+            result = rolesService.validateCurrentTenant(token, tenant);
+            return result;
+        }
+        result.put("message", "This resource no need validate");
+        return result;
+    }
+
     public void parsePulsarEvent(String path, HttpServletRequest request) {
         if (isNamespace(path, request)) {
             String[] tenantNamespace = path.split(SEPARATOR);
-            System.out.println(tenantNamespace);
-            System.out.println(tenantNamespace[0]);
-            System.out.println(tenantNamespace[1]);
-            System.out.println(tenantNamespace[2]);
             NamespaceEntity namespaceEntity = new NamespaceEntity();
-            System.out.println(tenantNamespace[4]);
-            System.out.println(tenantNamespace[5]);
             namespaceEntity.setTenant(tenantNamespace[4]);
             namespaceEntity.setNamespace(tenantNamespace[5]);
             namespacesRepository.save(namespaceEntity);
diff --git 
a/src/main/java/org/apache/pulsar/manager/service/impl/RoleBindingServiceImpl.java
 
b/src/main/java/org/apache/pulsar/manager/service/impl/RoleBindingServiceImpl.java
index 2e0cfa6..af0aa59 100644
--- 
a/src/main/java/org/apache/pulsar/manager/service/impl/RoleBindingServiceImpl.java
+++ 
b/src/main/java/org/apache/pulsar/manager/service/impl/RoleBindingServiceImpl.java
@@ -140,4 +140,38 @@ public class RoleBindingServiceImpl implements 
RoleBindingService {
         });
         return userRoleInfo;
     }
+    public List<Map<String, Object>> getAllRoleBindingList() {
+        List<RoleBindingEntity> roleBindingEntityList = 
roleBindingRepository.findAllRoleBindingList();
+        List<Long> roleIdList = new ArrayList<>();
+        List<Long> userIdList = new ArrayList<>();
+        roleBindingEntityList.forEach((roleBinding) -> {
+            roleIdList.add(roleBinding.getRoleId());
+            userIdList.add(roleBinding.getUserId());
+        });
+        List<UserInfoEntity> userInfoEntities = 
usersRepository.findUsersListByMultiUserId(userIdList);
+        Map<Long, UserInfoEntity> userInfoEntityMap = Maps.newHashMap();
+        userInfoEntities.forEach((u) -> {
+            userInfoEntityMap.put(u.getUserId(), u);
+        });
+        List<RoleInfoEntity> roleInfoEntities = 
rolesRepository.findAllRolesByMultiId(roleIdList);
+        Map<Long, RoleInfoEntity> roleInfoEntityMap = Maps.newHashMap();
+        roleInfoEntities.forEach((r) -> {
+            roleInfoEntityMap.put(r.getRoleId(), r);
+        });
+        List<Map<String, Object>> userRoleInfo = new ArrayList<>();
+        roleBindingEntityList.forEach((binding) -> {
+            RoleInfoEntity roleInfoEntity = 
roleInfoEntityMap.get(binding.getRoleId());
+            Map<String, Object> map = Maps.newHashMap();
+            map.put("name", binding.getName());
+            map.put("description", binding.getDescription());
+            map.put("userId", binding.getUserId());
+            if (userInfoEntityMap.get(binding.getUserId()) != null) {
+                map.put("userName", 
userInfoEntityMap.get(binding.getUserId()).getName());
+            }
+            map.put("roleId", binding.getRoleId());
+            map.put("roleName", roleInfoEntity.getRoleName());
+            userRoleInfo.add(map);
+        });
+        return userRoleInfo;
+    }
 }
diff --git 
a/src/main/java/org/apache/pulsar/manager/service/impl/RolesServiceImpl.java 
b/src/main/java/org/apache/pulsar/manager/service/impl/RolesServiceImpl.java
index fb38855..cd6f61f 100644
--- a/src/main/java/org/apache/pulsar/manager/service/impl/RolesServiceImpl.java
+++ b/src/main/java/org/apache/pulsar/manager/service/impl/RolesServiceImpl.java
@@ -13,7 +13,6 @@
  */
 package org.apache.pulsar.manager.service.impl;
 
-import com.github.pagehelper.Page;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import lombok.extern.slf4j.Slf4j;
@@ -152,8 +151,9 @@ public class RolesServiceImpl implements RolesService {
         return validateResult;
     }
 
-    public void createDefaultRoleAndTenant(String tenant) {
+    public Map<String, String> createDefaultRoleAndTenant(String tenant, 
String environment) {
         Optional<RoleInfoEntity> roleInfoEntityOptional = 
rolesRepository.findByRoleName(tenant, tenant);
+        Map<String, String> result = Maps.newHashMap();
         if (!roleInfoEntityOptional.isPresent()) {
             // Create role, create default tenant for user
             RoleInfoEntity roleInfoEntity = new RoleInfoEntity();
@@ -163,38 +163,37 @@ public class RolesServiceImpl implements RolesService {
             roleInfoEntity.setResourceName(tenant);
             roleInfoEntity.setResourceVerbs(ResourceVerbs.ADMIN.name());
             roleInfoEntity.setFlag(1);
-            try {
-                Page<EnvironmentEntity> environmentListPage =
-                        environmentsRepository.getEnvironmentsList(1, 1);
-                EnvironmentEntity environmentEntity = 
environmentListPage.get(0);
-                String broker = environmentEntity.getBroker();
-                List<String> clusterList = 
clustersService.getClusterByAnyBroker(broker);
-                tenantsService.createTenant(tenant, tenant, 
clusterList.get(0), broker);
-
-                // Cache default tenant
-                TenantEntity tenantEntity = new TenantEntity();
-                tenantEntity.setTenant(tenant);
-                tenantEntity.setAdminRoles(tenant);
-                tenantEntity.setAllowedClusters(clusterList.get(0));
-                long tenantId = tenantsRepository.save(tenantEntity);
-                roleInfoEntity.setResourceId(tenantId);
-                long roleId = rolesRepository.save(roleInfoEntity);
-                RoleBindingEntity roleBindingEntity = new RoleBindingEntity();
-                roleBindingEntity.setName(tenant);
-                roleBindingEntity.setDescription("This init binding for 
tenant");
-                roleBindingEntity.setRoleId(roleId);
-                Optional<UserInfoEntity> userInfoEntity = 
usersRepository.findByUserName(tenant);
-                roleBindingEntity.setUserId(userInfoEntity.get().getUserId());
-                roleBindingRepository.save(roleBindingEntity);
-            } catch (Exception e) {
-                /**
-                 * TO DO
-                 * Send a notification to the administrator so that the 
administrator can complete subsequent
-                 * operations without blocking user login.
-                 */
-                log.error("Create tenant failed: {}", e.getCause());
+            Optional<EnvironmentEntity> environmentEntityOptional = 
environmentsRepository.findByName(environment);
+            EnvironmentEntity environmentEntity = 
environmentEntityOptional.get();
+            if (!environmentEntityOptional.isPresent()) {
+                result.put("error", "Environment is no exist");
+                return result;
             }
+            String broker = environmentEntity.getBroker();
+            List<String> clusterList = 
clustersService.getClusterByAnyBroker(broker);
+            tenantsService.createTenant(tenant, tenant, clusterList.get(0), 
broker);
+
+            // Cache default tenant
+            TenantEntity tenantEntity = new TenantEntity();
+            tenantEntity.setTenant(tenant);
+            tenantEntity.setAdminRoles(tenant);
+            tenantEntity.setEnvironmentName(environment);
+            tenantEntity.setAllowedClusters(clusterList.get(0));
+            long tenantId = tenantsRepository.save(tenantEntity);
+            roleInfoEntity.setResourceId(tenantId);
+            long roleId = rolesRepository.save(roleInfoEntity);
+            RoleBindingEntity roleBindingEntity = new RoleBindingEntity();
+            roleBindingEntity.setName(tenant);
+            roleBindingEntity.setDescription("This init binding for tenant");
+            roleBindingEntity.setRoleId(roleId);
+            Optional<UserInfoEntity> userInfoEntity = 
usersRepository.findByUserName(tenant);
+            roleBindingEntity.setUserId(userInfoEntity.get().getUserId());
+            roleBindingRepository.save(roleBindingEntity);
+            result.put("message", "Create default success");
+            return result;
         }
+        result.put("error", "Role is exist");
+        return result;
     }
 
     public Set<String> getResourceVerbs(String resourceType) {
@@ -248,4 +247,23 @@ public class RolesServiceImpl implements RolesService {
         result.put("message", "Validate tenant success");
         return result;
     }
+    public boolean isSuperUser(String token) {
+        Optional<UserInfoEntity> userInfoEntityOptional = 
usersRepository.findByAccessToken(token);
+        if (!userInfoEntityOptional.isPresent()) {
+            return false;
+        }
+        UserInfoEntity userInfoEntity = userInfoEntityOptional.get();
+        List<RoleBindingEntity> roleBindingEntities = 
roleBindingRepository.findByUserId(userInfoEntity.getUserId());
+        List<Long> roleIdList = new ArrayList<>();
+        for (RoleBindingEntity roleBindingEntity : roleBindingEntities) {
+            roleIdList.add(roleBindingEntity.getRoleId());
+        }
+        List<RoleInfoEntity> roleInfoEntities = 
rolesRepository.findAllRolesByMultiId(roleIdList);
+        for (RoleInfoEntity roleInfoEntity : roleInfoEntities) {
+            if (roleInfoEntity.getFlag() == 0) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git 
a/src/main/java/org/apache/pulsar/manager/zuul/EnvironmentForward.java 
b/src/main/java/org/apache/pulsar/manager/zuul/EnvironmentForward.java
index 068ce0f..e17f154 100644
--- a/src/main/java/org/apache/pulsar/manager/zuul/EnvironmentForward.java
+++ b/src/main/java/org/apache/pulsar/manager/zuul/EnvironmentForward.java
@@ -13,8 +13,6 @@
  */
 package org.apache.pulsar.manager.zuul;
 
-import org.apache.pulsar.manager.entity.NamespaceEntity;
-import org.apache.pulsar.manager.entity.NamespacesRepository;
 import org.apache.pulsar.manager.service.EnvironmentCacheService;
 import com.netflix.zuul.ZuulFilter;
 import com.netflix.zuul.context.RequestContext;
@@ -30,6 +28,7 @@ import org.springframework.stereotype.Component;
 import javax.servlet.http.HttpServletRequest;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Map;
 
 import static 
org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
 import static 
org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY;
@@ -42,13 +41,13 @@ public class EnvironmentForward extends ZuulFilter {
 
     private static final Logger log = 
LoggerFactory.getLogger(EnvironmentForward.class);
 
-    private final PulsarEvent pulsarEvent;
-
     @Value("${backend.jwt.token}")
     private String pulsarJwtToken;
 
     private final EnvironmentCacheService environmentCacheService;
 
+    private final PulsarEvent pulsarEvent;
+
     @Autowired
     public EnvironmentForward(
             EnvironmentCacheService environmentCacheService, PulsarEvent 
pulsarEvent) {
@@ -78,6 +77,25 @@ public class EnvironmentForward extends ZuulFilter {
         HttpServletRequest request = ctx.getRequest();
         String redirect = request.getParameter("redirect");
 
+        String requestUri = request.getRequestURI();
+        String token = request.getHeader("token");
+
+        if (!pulsarEvent.validateRoutePermission(requestUri, token)) {
+            ctx.setResponseBody("This operation does not have permission");
+            return null;
+        }
+        if (requestUri.startsWith("/admin/v2/tenants/")
+                || requestUri.startsWith("/admin/v2/namespaces")
+                || requestUri.startsWith("/admin/v2/persistent")
+                || requestUri.startsWith("/admin/v2/non-persistent")) {
+            Map<String, String> result = pulsarEvent.validateTenantPermission(
+                    requestUri, token);
+            if (result.get("error") != null) {
+                log.error("This operation does not have permission");
+                ctx.setResponseBody(result.get("error"));
+                return null;
+            }
+        }
         if (redirect != null && redirect.equals("true")) {
             String redirectScheme = request.getParameter("redirect.scheme");
             String redirectHost = request.getParameter("redirect.host");
diff --git a/src/main/resources/META-INF/sql/herddb-schema.sql 
b/src/main/resources/META-INF/sql/herddb-schema.sql
index 00d65f5..ddcebbb 100644
--- a/src/main/resources/META-INF/sql/herddb-schema.sql
+++ b/src/main/resources/META-INF/sql/herddb-schema.sql
@@ -143,32 +143,8 @@ CREATE TABLE IF NOT EXISTS tenants (
   tenant_id BIGINT PRIMARY KEY AUTO_INCREMENT,
   tenant varchar(255) NOT NULL,
   admin_roles varchar(255),
-  allowed_clusters varchar(255)
-);
-
-CREATE TABLE IF NOT EXISTS namespaces (
-  namespace_id BIGINT PRIMARY KEY AUTO_INCREMENT,
-  tenant varchar(255) NOT NULL,
-  namespace varchar(255) NOT NULL
-);
-
-CREATE TABLE IF NOT EXISTS roles (
-  role_id BIGINT PRIMARY KEY AUTO_INCREMENT,
-  role_name varchar(256) NOT NULL,
-  role_source varchar(256) NOT NULL,
-  description varchar(128),
-  resource_id BIGINT NOT NULL,
-  resource_type varchar(48) NOT NULL,
-  resource_name varchar(48) NOT NULL,
-  resource_verbs varchar(256) NOT NULL,
-  flag INT NOT NULL
-);
-
-CREATE TABLE IF NOT EXISTS tenants (
-  tenant_id BIGINT PRIMARY KEY AUTO_INCREMENT,
-  tenant varchar(255) NOT NULL,
-  admin_roles varchar(255),
-  allowed_clusters varchar(255)
+  allowed_clusters varchar(255),
+  environment_name varchar(255)
 );
 
 CREATE TABLE IF NOT EXISTS namespaces (
diff --git a/src/main/resources/META-INF/sql/mysql-schema.sql 
b/src/main/resources/META-INF/sql/mysql-schema.sql
index f3727bc..5bc57e2 100644
--- a/src/main/resources/META-INF/sql/mysql-schema.sql
+++ b/src/main/resources/META-INF/sql/mysql-schema.sql
@@ -147,8 +147,7 @@ CREATE TABLE IF NOT EXISTS roles (
   resource_type varchar(48) NOT NULL,
   resource_name varchar(48) NOT NULL,
   resource_verbs varchar(256) NOT NULL,
-  flag INT NOT NULL,
-  UNIQUE(role_name, role_source)
+  flag INT NOT NULL
 )ENGINE=InnoDB CHARACTER SET utf8;
 
 CREATE TABLE IF NOT EXISTS tenants (
@@ -156,6 +155,7 @@ CREATE TABLE IF NOT EXISTS tenants (
   tenant varchar(255) NOT NULL,
   admin_roles varchar(255),
   allowed_clusters varchar(255),
+  environment_name varchar(255)
   UNIQUE(tenant)
 )ENGINE=InnoDB CHARACTER SET utf8;
 
@@ -164,4 +164,12 @@ CREATE TABLE IF NOT EXISTS namespaces (
   tenant varchar(255) NOT NULL,
   namespace varchar(255) NOT NULL,
   UNIQUE(tenant, namespace)
+)ENGINE=InnoDB CHARACTER SET utf8;
+
+CREATE TABLE IF NOT EXISTS role_binding(
+  role_binding_id BIGINT PRIMARY KEY AUTO_INCREMENT,
+  name varchar(256) NOT NULL,
+  description varchar(256),
+  role_id BIGINT NOT NULL,
+  user_id BIGINT NOT NULL
 )ENGINE=InnoDB CHARACTER SET utf8;
\ No newline at end of file
diff --git a/src/main/resources/META-INF/sql/postgresql-schema.sql 
b/src/main/resources/META-INF/sql/postgresql-schema.sql
index e7e4183..8dcaa33 100644
--- a/src/main/resources/META-INF/sql/postgresql-schema.sql
+++ b/src/main/resources/META-INF/sql/postgresql-schema.sql
@@ -147,8 +147,7 @@ CREATE TABLE IF NOT EXISTS roles (
   resource_type varchar(48) NOT NULL,
   resource_name varchar(48) NOT NULL,
   resource_verbs varchar(256) NOT NULL,
-  flag INT NOT NULL,
-  UNIQUE(role_name, role_source)
+  flag INT NOT NULL
 );
 
 CREATE TABLE IF NOT EXISTS tenants (
@@ -156,6 +155,7 @@ CREATE TABLE IF NOT EXISTS tenants (
   tenant varchar(255) NOT NULL,
   admin_roles varchar(255),
   allowed_clusters varchar(255),
+  environment_name varchar(255),
   UNIQUE(tenant)
 );
 
@@ -164,4 +164,12 @@ CREATE TABLE IF NOT EXISTS namespaces (
   tenant varchar(255) NOT NULL,
   namespace varchar(255) NOT NULL,
   UNIQUE(tenant, namespace)
+);
+
+CREATE TABLE IF NOT EXISTS role_binding(
+  role_binding_id BIGINT PRIMARY KEY AUTO_INCREMENT,
+  name varchar(256) NOT NULL,
+  description varchar(256),
+  role_id BIGINT NOT NULL,
+  user_id BIGINT NOT NULL
 );
\ No newline at end of file
diff --git a/src/main/resources/META-INF/sql/sqlite-schema.sql 
b/src/main/resources/META-INF/sql/sqlite-schema.sql
index 3dd24af..e1572a5 100644
--- a/src/main/resources/META-INF/sql/sqlite-schema.sql
+++ b/src/main/resources/META-INF/sql/sqlite-schema.sql
@@ -143,8 +143,7 @@ CREATE TABLE IF NOT EXISTS roles (
   resource_type varchar(48) NOT NULL,
   resource_name varchar(48) NOT NULL,
   resource_verbs varchar(256) NOT NULL,
-  flag INT NOT NULL,
-  UNIQUE(role_name, role_source)
+  flag INT NOT NULL
 );
 
 CREATE TABLE IF NOT EXISTS tenants (
@@ -152,6 +151,7 @@ CREATE TABLE IF NOT EXISTS tenants (
   tenant varchar(255) NOT NULL,
   admin_roles varchar(255),
   allowed_clusters varchar(255),
+  environment_name varchar(255),
   UNIQUE(tenant)
 );
 
@@ -161,3 +161,12 @@ CREATE TABLE IF NOT EXISTS namespaces (
   namespace varchar(255) NOT NULL,
   UNIQUE(tenant, namespace)
 );
+
+CREATE TABLE IF NOT EXISTS role_binding(
+  role_binding_id BIGINT PRIMARY KEY AUTO_INCREMENT,
+  name varchar(256) NOT NULL,
+  description varchar(256),
+  role_id BIGINT NOT NULL,
+  user_id BIGINT NOT NULL,
+  UNIQUE(role_id, user_id)
+);
diff --git 
a/src/test/java/org/apache/pulsar/manager/dao/NamespacesRepositoryImplTest.java 
b/src/test/java/org/apache/pulsar/manager/dao/NamespacesRepositoryImplTest.java
index be96233..c8e2efe 100644
--- 
a/src/test/java/org/apache/pulsar/manager/dao/NamespacesRepositoryImplTest.java
+++ 
b/src/test/java/org/apache/pulsar/manager/dao/NamespacesRepositoryImplTest.java
@@ -81,7 +81,8 @@ public class NamespacesRepositoryImplTest {
 
     public void prepareTenant() {
         TenantEntity tenantsEntity = new TenantEntity(
-                1, "test-namespace-public",  "testrole", "testCluster");
+                1, "test-namespace-public",
+                "testrole", "testCluster", "test-environment");
         tenantsRepository.save(tenantsEntity);
     }
 
diff --git 
a/src/test/java/org/apache/pulsar/manager/dao/TenantsRepositoryImplTest.java 
b/src/test/java/org/apache/pulsar/manager/dao/TenantsRepositoryImplTest.java
index 54b09cf..d37d719 100644
--- a/src/test/java/org/apache/pulsar/manager/dao/TenantsRepositoryImplTest.java
+++ b/src/test/java/org/apache/pulsar/manager/dao/TenantsRepositoryImplTest.java
@@ -50,6 +50,7 @@ public class TenantsRepositoryImplTest {
             tenantEntity.setTenant("test" + i);
             tenantEntity.setAdminRoles("test" + i);
             tenantEntity.setAllowedClusters("test-cluster");
+            tenantEntity.setEnvironmentName("test-environment");
             tenantsRepository.save(tenantEntity);
         }
         Page<TenantEntity> tenantsEntities = 
tenantsRepository.getTenantsList(1, 10);
@@ -61,6 +62,7 @@ public class TenantsRepositoryImplTest {
             TenantEntity tenantEntity = tenantsEntityList.get(i);
             Assert.assertEquals(tenantEntity.getTenant(), 
tenantEntity.getAdminRoles());
             Assert.assertEquals(tenantEntity.getAllowedClusters(), 
"test-cluster");
+            Assert.assertEquals(tenantEntity.getEnvironmentName(), 
"test-environment");
         }
         tenantsEntities.getResult().forEach((result) -> {
             tenantsRepository.remove(result.getTenant());
@@ -75,6 +77,7 @@ public class TenantsRepositoryImplTest {
             tenantEntity.setTenant("test" + i);
             tenantEntity.setAdminRoles("test" + i);
             tenantEntity.setAllowedClusters("test-cluster");
+            tenantEntity.setEnvironmentName("test-environment");
             Long tenantId = tenantsRepository.save(tenantEntity);
             idList.add(tenantId);
         }
@@ -87,6 +90,7 @@ public class TenantsRepositoryImplTest {
             TenantEntity tenantEntity = tenantsEntityList.get(i);
             Assert.assertEquals(tenantEntity.getTenant(), 
tenantEntity.getAdminRoles());
             Assert.assertEquals(tenantEntity.getAllowedClusters(), 
"test-cluster");
+            Assert.assertEquals(tenantEntity.getEnvironmentName(), 
"test-environment");
         }
         tenantEntityPage.getResult().forEach((result) -> {
             tenantsRepository.remove(result.getTenant());
@@ -99,12 +103,14 @@ public class TenantsRepositoryImplTest {
         tenantEntity.setTenant("test");
         tenantEntity.setAdminRoles("test-role");
         tenantEntity.setAllowedClusters("test-cluster");
+        tenantEntity.setEnvironmentName("test-environment");
         tenantsRepository.save(tenantEntity);
         Optional<TenantEntity> result = tenantsRepository.findByName("test");
         TenantEntity getTenantEntity = result.get();
         Assert.assertEquals(getTenantEntity.getTenant(), "test");
         Assert.assertEquals(getTenantEntity.getAdminRoles(), "test-role");
         Assert.assertEquals(getTenantEntity.getAllowedClusters(), 
"test-cluster");
+        Assert.assertEquals(getTenantEntity.getEnvironmentName(), 
"test-environment");
         tenantsRepository.remove("test");
     }
 
@@ -114,11 +120,13 @@ public class TenantsRepositoryImplTest {
         tenantEntity.setTenant("test");
         tenantEntity.setAdminRoles("test-role");
         tenantEntity.setAllowedClusters("test-cluster");
+        tenantEntity.setEnvironmentName("test-environment");
         long tenantId = tenantsRepository.save(tenantEntity);
         Optional<TenantEntity> result = 
tenantsRepository.findByTenantId(tenantId);
         TenantEntity getTenantEntity = result.get();
         Assert.assertEquals(getTenantEntity.getTenant(), "test");
         Assert.assertEquals(getTenantEntity.getAdminRoles(), "test-role");
         Assert.assertEquals(getTenantEntity.getAllowedClusters(), 
"test-cluster");
+        Assert.assertEquals(getTenantEntity.getEnvironmentName(), 
"test-environment");
     }
 }
\ No newline at end of file
diff --git 
a/src/test/java/org/apache/pulsar/manager/service/PulsarEventImplTest.java 
b/src/test/java/org/apache/pulsar/manager/service/PulsarEventImplTest.java
new file mode 100644
index 0000000..df518ac
--- /dev/null
+++ b/src/test/java/org/apache/pulsar/manager/service/PulsarEventImplTest.java
@@ -0,0 +1,192 @@
+/**
+ * Licensed 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.
+ */
+package org.apache.pulsar.manager.service;
+
+import org.apache.pulsar.manager.PulsarManagerApplication;
+import org.apache.pulsar.manager.entity.NamespaceEntity;
+import org.apache.pulsar.manager.entity.NamespacesRepository;
+import org.apache.pulsar.manager.entity.RoleBindingEntity;
+import org.apache.pulsar.manager.entity.RoleBindingRepository;
+import org.apache.pulsar.manager.entity.RoleInfoEntity;
+import org.apache.pulsar.manager.entity.RolesRepository;
+import org.apache.pulsar.manager.entity.TenantEntity;
+import org.apache.pulsar.manager.entity.TenantsRepository;
+import org.apache.pulsar.manager.entity.UserInfoEntity;
+import org.apache.pulsar.manager.entity.UsersRepository;
+import org.apache.pulsar.manager.profiles.HerdDBTestProfile;
+import org.apache.pulsar.manager.utils.ResourceType;
+import org.apache.pulsar.manager.utils.ResourceVerbs;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.Map;
+import java.util.Optional;
+
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(SpringRunner.class)
+@PowerMockIgnore( {"javax.*", "sun.*", "com.sun.*", "org.xml.*", "org.w3c.*"})
+@SpringBootTest(
+        classes = {
+                PulsarManagerApplication.class,
+                HerdDBTestProfile.class
+        }
+)
+@ActiveProfiles("test")
+public class PulsarEventImplTest {
+
+    @Autowired
+    private PulsarEvent pulsarEvent;
+
+    @Autowired
+    private UsersRepository usersRepository;
+
+    @Autowired
+    private RolesRepository rolesRepository;
+
+    @Autowired
+    private RoleBindingRepository roleBindingRepository;
+
+    @Autowired
+    private TenantsRepository tenantsRepository;
+
+    @Autowired
+    private NamespacesRepository namespacesRepository;
+
+    private long superUserId, superRoleId, adminUserId, adminRoleId;
+
+    @Before
+    public void setup() {
+        // prepare super user
+        UserInfoEntity superUserInfoEntity = new UserInfoEntity();
+        superUserInfoEntity.setName("superuser");
+        superUserInfoEntity.setAccessToken("super-access-token");
+        superUserId = usersRepository.save(superUserInfoEntity);
+        TenantEntity superTenantEntity = new TenantEntity();
+        superTenantEntity.setTenant("superTenant");
+        superTenantEntity.setAdminRoles("super-admin-roles");
+        superTenantEntity.setAllowedClusters("super-allowed-clusters");
+        long superTenantId = tenantsRepository.save(superTenantEntity);
+        RoleInfoEntity superRoleInfoEntity = new RoleInfoEntity();
+        superRoleInfoEntity.setRoleName("super-role");
+        superRoleInfoEntity.setRoleSource("superTenant");
+        superRoleInfoEntity.setResourceId(superTenantId);
+        superRoleInfoEntity.setFlag(0);
+        superRoleInfoEntity.setResourceName("super-tenant-resource");
+        superRoleInfoEntity.setResourceType(ResourceType.TENANTS.name());
+        superRoleInfoEntity.setResourceVerbs(ResourceVerbs.ADMIN.name());
+        superRoleId = rolesRepository.save(superRoleInfoEntity);
+        RoleBindingEntity superRoleBindingEntity = new RoleBindingEntity();
+        superRoleBindingEntity.setDescription("This is role binding 
description");
+        superRoleBindingEntity.setUserId(superUserId);
+        superRoleBindingEntity.setRoleId(superRoleId);
+        superRoleBindingEntity.setName("super-role-binding");
+        roleBindingRepository.save(superRoleBindingEntity);
+
+        // prepare admin user
+        UserInfoEntity adminUserInfoEntity = new UserInfoEntity();
+        adminUserInfoEntity.setName("admin");
+        adminUserInfoEntity.setAccessToken("admin-access-token");
+        adminUserId = usersRepository.save(adminUserInfoEntity);
+        TenantEntity adminTenantEntity = new TenantEntity();
+        adminTenantEntity.setTenant("adminTenant");
+        adminTenantEntity.setAdminRoles("super-admin-roles");
+        adminTenantEntity.setAllowedClusters("super-allowed-clusters");
+        long adminTenantId = tenantsRepository.save(adminTenantEntity);
+        RoleInfoEntity adminRoleInfoEntity = new RoleInfoEntity();
+        adminRoleInfoEntity.setRoleName("admin-role");
+        adminRoleInfoEntity.setRoleSource("adminTenant");
+        adminRoleInfoEntity.setResourceId(adminTenantId);
+        adminRoleInfoEntity.setFlag(1);
+        adminRoleInfoEntity.setResourceName("admin-tenant-resource");
+        adminRoleInfoEntity.setResourceType(ResourceType.TENANTS.name());
+        adminRoleInfoEntity.setResourceVerbs(ResourceVerbs.ADMIN.name());
+        adminRoleId = rolesRepository.save(adminRoleInfoEntity);
+        RoleBindingEntity adminRoleBindingEntity = new RoleBindingEntity();
+        adminRoleBindingEntity.setDescription("This is role binding 
description");
+        adminRoleBindingEntity.setUserId(adminUserId);
+        adminRoleBindingEntity.setRoleId(adminRoleId);
+        adminRoleBindingEntity.setName("admin-role-binding");
+        roleBindingRepository.save(adminRoleBindingEntity);
+    }
+
+    @After
+    public void clear() {
+        usersRepository.delete("superuser");
+        usersRepository.delete("admin");
+        tenantsRepository.remove("superTenant");
+        tenantsRepository.remove("adminTenant");
+        rolesRepository.delete("super-role", "superTenant");
+        rolesRepository.delete("admin-role", "adminTenant");
+        roleBindingRepository.delete(superRoleId, adminUserId);
+        roleBindingRepository.delete(adminRoleId, adminUserId);
+    }
+
+    @Test
+    public void validateRoutePermissionTest() {
+        
Assert.assertTrue(pulsarEvent.validateRoutePermission("/admin/v2/clusters", 
"super-access-token"));
+        
Assert.assertTrue(pulsarEvent.validateRoutePermission("/admin/v2/brokers", 
"super-access-token"));
+        Assert.assertTrue(
+                pulsarEvent.validateRoutePermission("/admin/v2/broker-stats", 
"super-access-token"));
+        Assert.assertTrue(
+                
pulsarEvent.validateRoutePermission("/admin/v2/resource-quotas", 
"super-access-token"));
+
+        
Assert.assertFalse(pulsarEvent.validateRoutePermission("/admin/v2/clusters", 
"admin-access-token"));
+        
Assert.assertFalse(pulsarEvent.validateRoutePermission("/admin/v2/brokers", 
"admin-access-token"));
+        Assert.assertFalse(
+                pulsarEvent.validateRoutePermission("/admin/v2/broker-stats", 
"admin-access-token"));
+        Assert.assertFalse(
+                
pulsarEvent.validateRoutePermission("/admin/v2/resource-quotas", 
"admin-access-token"));
+
+        
Assert.assertTrue(pulsarEvent.validateRoutePermission("/admin/v2/tenants", 
"admin-access-token"));
+    }
+
+    @Test
+    public void validateTenantPermission() {
+        Map<String, String> result;
+        result = 
pulsarEvent.validateTenantPermission("/admin/v2/tenants/superTenant", 
"super-access-token");
+        Assert.assertEquals(result.get("message"), "Validate tenant success");
+        result = 
pulsarEvent.validateTenantPermission("/admin/v2/tenants/adminTenant", 
"super-access-token");
+        Assert.assertEquals(result.get("error"), "This user no include this 
tenant");
+
+        result = pulsarEvent.validateTenantPermission(
+                
"/pulsar-manager/admin/v2/schemas/adminTenant/default/test-topic", 
"super-access-token");
+        Assert.assertEquals(result.get("message"), "This resource no need 
validate");
+
+        result = pulsarEvent.validateTenantPermission(
+                "/pulsar-manager/admin/v2/namespaces/adminTenant/default", 
"admin-access-token");
+        Assert.assertEquals(result.get("message"), "Validate tenant success");
+    }
+
+    @Test
+    public void parsePulsarEvent() {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setMethod("PUT");
+        
pulsarEvent.parsePulsarEvent("/admin/v2/namespaces/adminTenant/default/test-topic",
 request);
+        Optional<NamespaceEntity> namespaceEntity = 
namespacesRepository.findByTenantNamespace(
+                "adminTenant", "default");
+        Assert.assertTrue(namespaceEntity.isPresent());
+    }
+}

Reply via email to