add user detail module

This commit is contained in:
许晓东
2021-09-07 17:28:11 +08:00
parent 139037ef26
commit 9e01d244f9
8 changed files with 147 additions and 85 deletions

View File

@@ -0,0 +1,21 @@
package com.xuxd.kafka.console.beans.vo;
import lombok.Data;
/**
* kafka-console-ui.
*
* @author xuxd
* @date 2021-09-07 14:10:10
**/
@Data
public class KafkaUserDetailVO {
private String username;
private String password;
private String credentialInfos;
private String consistencyDescription;
}

View File

@@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
/** /**
@@ -43,4 +44,9 @@ public class AclUserController {
public Object deleteUserAndAuth(@RequestBody AclUser user) { public Object deleteUserAndAuth(@RequestBody AclUser user) {
return aclService.deleteUserAndAuth(user.getUsername()); return aclService.deleteUserAndAuth(user.getUsername());
} }
@GetMapping("/detail")
public Object getUserDetail(@RequestParam String username) {
return aclService.getUserDetail(username);
}
} }

View File

@@ -5,6 +5,7 @@ import com.xuxd.kafka.console.beans.CounterList;
import com.xuxd.kafka.console.beans.CounterMap; import com.xuxd.kafka.console.beans.CounterMap;
import com.xuxd.kafka.console.beans.ResponseData; import com.xuxd.kafka.console.beans.ResponseData;
import com.xuxd.kafka.console.beans.dos.KafkaUserDO; import com.xuxd.kafka.console.beans.dos.KafkaUserDO;
import com.xuxd.kafka.console.beans.vo.KafkaUserDetailVO;
import com.xuxd.kafka.console.config.KafkaConfig; import com.xuxd.kafka.console.config.KafkaConfig;
import com.xuxd.kafka.console.dao.KafkaUserMapper; import com.xuxd.kafka.console.dao.KafkaUserMapper;
import com.xuxd.kafka.console.service.AclService; import com.xuxd.kafka.console.service.AclService;
@@ -77,7 +78,7 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton {
map.put("username", name); map.put("username", name);
kafkaUserMapper.deleteByMap(map); kafkaUserMapper.deleteByMap(map);
kafkaUserMapper.insert(userDO); kafkaUserMapper.insert(userDO);
}catch (Exception e) { } catch (Exception e) {
log.error("kafkaUserMapper.insert error.", e); log.error("kafkaUserMapper.insert error.", e);
return ResponseData.create().failed(e.getMessage()); return ResponseData.create().failed(e.getMessage());
} }
@@ -107,7 +108,7 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton {
} }
@Override public ResponseData getAclDetailList(AclEntry entry) { @Override public ResponseData getAclDetailList(AclEntry entry) {
List<AclBinding> aclBindingList = entry ==null || entry.isNull() ? aclConsole.getAclList(null) : aclConsole.getAclList(entry); List<AclBinding> aclBindingList = entry == null || entry.isNull() ? aclConsole.getAclList(null) : aclConsole.getAclList(entry);
return ResponseData.create().data(new CounterList<>(aclBindingList.stream().map(x -> AclEntry.valueOf(x)).collect(Collectors.toList()))).success(); return ResponseData.create().data(new CounterList<>(aclBindingList.stream().map(x -> AclEntry.valueOf(x)).collect(Collectors.toList()))).success();
} }
@@ -182,15 +183,26 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton {
} }
@Override public ResponseData getUserDetail(String username) { @Override public ResponseData getUserDetail(String username) {
KafkaUserDetailVO vo = new KafkaUserDetailVO();
vo.setUsername(username);
Map<String, UserScramCredentialsDescription> detailList = configConsole.getUserDetailList(Collections.singletonList(username));
if (!detailList.isEmpty() && detailList.containsKey(username)) {
UserScramCredentialsDescription description = detailList.get(username);
String credentialInfo = StringUtils.join(description.credentialInfos(), ";");
vo.setCredentialInfos(credentialInfo);
}
Map<String, Object> param = new HashMap<>(); Map<String, Object> param = new HashMap<>();
param.put("username", username); param.put("username", username);
List<KafkaUserDO> dos = kafkaUserMapper.selectByMap(param); List<KafkaUserDO> dos = kafkaUserMapper.selectByMap(param);
if (dos.isEmpty()) { if (dos.isEmpty()) {
return ResponseData.create().data(new CounterList<>(dos)).success("Retrieved the user info is null."); vo.setConsistencyDescription("Password is null.");
} else {
vo.setPassword(dos.stream().findFirst().get().getPassword());
} }
// check for consistency. // check for consistency.
return null; return ResponseData.create().data(vo).success();
} }
@Override public void afterSingletonsInstantiated() { @Override public void afterSingletonsInstantiated() {

View File

@@ -3,6 +3,10 @@ export const KafkaAclApi = {
url: "/user", url: "/user",
method: "post", method: "post",
}, },
getKafkaUserDetail: {
url: "/user/detail",
method: "get",
},
deleteKafkaUser: { deleteKafkaUser: {
url: "/user/auth", url: "/user/auth",
method: "delete", method: "delete",

View File

@@ -63,10 +63,6 @@
@click="onUserDetail(username)" @click="onUserDetail(username)"
>详情</a-button >详情</a-button
> >
<UserDetail
:visible="openUserDetailDialog"
@userDetailDialog="closeUserDetailDialog"
></UserDetail>
</div> </div>
<div slot="topicList" slot-scope="topicList, record"> <div slot="topicList" slot-scope="topicList, record">
@@ -77,11 +73,6 @@
@click="onTopicDetail(t, record.username)" @click="onTopicDetail(t, record.username)"
><div style="border-bottom: 1px solid #e5e1e1">{{ t }}</div> ><div style="border-bottom: 1px solid #e5e1e1">{{ t }}</div>
</a> </a>
<AclDetail
:visible="openAclDetailDialog"
:selectDetail="selectDetail"
@aclDetailDialog="closeAclDetailDialog"
></AclDetail>
</div> </div>
<div slot="groupList" slot-scope="groupList, record"> <div slot="groupList" slot-scope="groupList, record">
@@ -115,11 +106,6 @@
class="operation-btn" class="operation-btn"
@click="onManageProducerAuth(record)" @click="onManageProducerAuth(record)"
>管理生产权限 >管理生产权限
<ManageProducerAuth
:visible="openManageProducerAuthDialog"
:record="selectRow"
@manageProducerAuthDialog="closeManageProducerAuthDialog"
></ManageProducerAuth>
</a-button> </a-button>
<a-button <a-button
@@ -128,11 +114,6 @@
class="operation-btn" class="operation-btn"
@click="onManageConsumerAuth(record)" @click="onManageConsumerAuth(record)"
>管理消费权限 >管理消费权限
<ManageConsumerAuth
:visible="openManageConsumerAuthDialog"
:record="selectRow"
@manageConsumerAuthDialog="closeManageConsumerAuthDialog"
></ManageConsumerAuth>
</a-button> </a-button>
<a-button <a-button
size="small" size="small"
@@ -140,14 +121,34 @@
class="operation-btn" class="operation-btn"
@click="onAddAuth(record)" @click="onAddAuth(record)"
>增加权限 >增加权限
<AddAuth
:visible="openAddAuthDialog"
:record="selectRow"
@addAuthDialog="closeAddAuthDialog"
></AddAuth>
</a-button> </a-button>
</div> </div>
</a-table> </a-table>
<UserDetail
:visible="openUserDetailDialog"
:username="selectDetail.username"
@userDetailDialog="closeUserDetailDialog"
></UserDetail>
<AclDetail
:visible="openAclDetailDialog"
:selectDetail="selectDetail"
@aclDetailDialog="closeAclDetailDialog"
></AclDetail>
<ManageProducerAuth
:visible="openManageProducerAuthDialog"
:record="selectRow"
@manageProducerAuthDialog="closeManageProducerAuthDialog"
></ManageProducerAuth>
<ManageConsumerAuth
:visible="openManageConsumerAuthDialog"
:record="selectRow"
@manageConsumerAuthDialog="closeManageConsumerAuthDialog"
></ManageConsumerAuth>
<AddAuth
:visible="openAddAuthDialog"
:record="selectRow"
@addAuthDialog="closeAddAuthDialog"
></AddAuth>
</div> </div>
</div> </div>
</template> </template>
@@ -283,13 +284,17 @@ export default {
this.openManageConsumerAuthDialog = false; this.openManageConsumerAuthDialog = false;
getAclList(this.data, this.queryParam); getAclList(this.data, this.queryParam);
}, },
closeAddAuthDialog() { closeAddAuthDialog(p) {
this.openAddAuthDialog = false; this.openAddAuthDialog = false;
getAclList(this.data, this.queryParam); if (p.refresh) {
getAclList(this.data, this.queryParam);
}
}, },
closeAclDetailDialog() { closeAclDetailDialog(p) {
this.openAclDetailDialog = false; this.openAclDetailDialog = false;
getAclList(this.data, this.queryParam); if (p.refresh) {
getAclList(this.data, this.queryParam);
}
}, },
closeUserDetailDialog() { closeUserDetailDialog() {
this.openUserDetailDialog = false; this.openUserDetailDialog = false;

View File

@@ -4,10 +4,7 @@
:visible="show" :visible="show"
:confirm-loading="confirmLoading" :confirm-loading="confirmLoading"
:width="1200" :width="1200"
@ok="handleOk"
@cancel="handleCancel" @cancel="handleCancel"
okText="提交"
cancelText="取消"
:mask="false" :mask="false"
:destroyOnClose="true" :destroyOnClose="true"
:footer="null" :footer="null"
@@ -69,32 +66,8 @@ export default {
}, },
}, },
methods: { methods: {
handleOk() {
const form = this.form;
form.validateFields((e, v) => {
if (e) {
return;
}
const param = Object.assign({}, v);
const api = KafkaAclApi.addAclAuth;
this.confirmLoading = true;
request({
url: api.url,
method: api.method,
data: param,
}).then((res) => {
this.confirmLoading = false;
if (res.code == 0) {
this.$message.success(res.msg);
this.$emit("aclDetailDialog", v);
} else {
this.$message.error(res.msg);
}
});
});
},
handleCancel() { handleCancel() {
this.$emit("aclDetailDialog", {}); this.$emit("aclDetailDialog", { refresh: true });
}, },
getAclDetail() { getAclDetail() {
const api = KafkaAclApi.getAclDetailList; const api = KafkaAclApi.getAclDetailList;

View File

@@ -98,7 +98,12 @@ export default {
}, },
watch: { watch: {
visible(v) { visible(v) {
this.show = v; if (this.show != v) {
this.show = v;
if (this.show) {
this.getOperationList();
}
}
}, },
}, },
methods: { methods: {
@@ -119,7 +124,7 @@ export default {
this.confirmLoading = false; this.confirmLoading = false;
if (res.code == 0) { if (res.code == 0) {
this.$message.success(res.msg); this.$message.success(res.msg);
this.$emit("addAuthDialog", v); this.$emit("addAuthDialog", { refresh: true });
} else { } else {
this.$message.error(res.msg); this.$message.error(res.msg);
} }
@@ -127,21 +132,21 @@ export default {
}); });
}, },
handleCancel() { handleCancel() {
this.$emit("addAuthDialog", {}); this.$emit("addAuthDialog", { refresh: false });
},
getOperationList() {
request({
url: KafkaAclApi.getOperationList.url,
method: KafkaAclApi.getOperationList.method,
}).then((res) => {
if (res.code != 0) {
this.$message.error(res.msg);
} else {
operationList.splice(0, operationList.length);
operationList.push(...res.data);
}
});
}, },
},
beforeMount() {
request({
url: KafkaAclApi.getOperationList.url,
method: KafkaAclApi.getOperationList.method,
}).then((res) => {
if (res.code != 0) {
this.$message.error(res.msg);
} else {
operationList.splice(0, operationList.length);
operationList.push(...res.data);
}
});
}, },
}; };
const operationList = []; const operationList = [];

View File

@@ -8,12 +8,31 @@
:footer="null" :footer="null"
@cancel="handleCancel" @cancel="handleCancel"
> >
<a-form
:form="form"
:label-col="{ span: 5 }"
:wrapper-col="{ span: 12 }"
@submit="handleSubmit"
>
<a-form-item label="用户名">
<span>{{ user.username }}</span>
</a-form-item>
<a-form-item label="密码">
<span>{{ user.password }}</span>
</a-form-item>
<a-form-item label="凭证信息">
<span>{{ user.credentialInfos }}</span>
</a-form-item>
<a-form-item label="数据一致性说明">
<strong>{{ user.consistencyDescription }}</strong>
</a-form-item>
</a-form>
</a-modal> </a-modal>
</template> </template>
<script> <script>
// import { KafkaAclApi } from "@/utils/api"; import { KafkaAclApi } from "@/utils/api";
// import request from "@/utils/request"; import request from "@/utils/request";
export default { export default {
name: "UserDetail", name: "UserDetail",
@@ -22,21 +41,24 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
username: {
type: String,
},
}, },
components: { components: {},
// KafkaAclApi, request,
},
data() { data() {
return { return {
formLayout: "horizontal", formLayout: "horizontal",
show: this.visible, show: this.visible,
form: this.$form.createForm(this, { name: "UserDetailForm" }),
user: {},
}; };
}, },
watch: { watch: {
visible(v) { visible(n, o) {
this.show = v; this.show = n;
if (this.show) { if (n != o && this.show) {
this.getAclDetail(); this.getUserDetail();
} }
}, },
}, },
@@ -44,6 +66,20 @@ export default {
handleCancel() { handleCancel() {
this.$emit("userDetailDialog", {}); this.$emit("userDetailDialog", {});
}, },
getUserDetail() {
const api = KafkaAclApi.getKafkaUserDetail;
request({
url: api.url,
method: api.method,
params: { username: this.username },
}).then((res) => {
if (res.code != 0) {
this.$message.error(res.msg);
} else {
this.user = res.data;
}
});
},
}, },
}; };
</script> </script>