mirror of
https://github.com/1Panel-dev/KubePi.git
synced 2026-04-22 16:27:10 +08:00
feat: 用户增加mfa设置
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@ set -e
|
||||
|
||||
arg1=$1
|
||||
mkdir -p ~/.kube
|
||||
code=`curl -w %{http_code} -s -o ~/.kube/config http://localhost/api/v1/webkubectl/session?token=${arg1}`
|
||||
code=`curl -w %{http_code} -s -o ~/.kube/config http://localhost/kubepi/api/v1/webkubectl/session?token=${arg1}`
|
||||
|
||||
if [[ $code -ne '200' ]];then
|
||||
echo "download kubeconfig failed"
|
||||
|
||||
@@ -11,6 +11,7 @@ type User struct {
|
||||
IsAdmin bool `json:"isAdmin"`
|
||||
Authenticate Authenticate `json:"authenticate"`
|
||||
Type string `json:"type"`
|
||||
Mfa Mfa `json:"mfa"`
|
||||
}
|
||||
|
||||
type Authenticate struct {
|
||||
@@ -18,6 +19,11 @@ type Authenticate struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type Mfa struct {
|
||||
Enable bool `json:"enable"`
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
|
||||
const (
|
||||
LDAP = "LDAP"
|
||||
LOCAL = "LOCAL"
|
||||
|
||||
Generated
+844
-846
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,32 @@
|
||||
<template xmlns:el-col="http://www.w3.org/1999/html">
|
||||
<div class="login-background">
|
||||
<!-- <el-row>-->
|
||||
<!-- <el-col>-->
|
||||
<!-- <div style="text-align: center">-->
|
||||
<!-- <div>-->
|
||||
<!-- <span>{{ $t("commons.login.mfa_helper") }}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div>-->
|
||||
<!-- <img :src="otp.qrUrl">-->
|
||||
<!-- </div>-->
|
||||
<!-- <div>-->
|
||||
<!-- <span>Secret:{{otp.secret}}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div>-->
|
||||
<!-- <el-form>-->
|
||||
<!-- <el-form-item class="login">-->
|
||||
<!-- <el-input></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-form>-->
|
||||
<!-- <div>-->
|
||||
<!-- <el-button type="primary" class="submit" @click="submit('form')" size="default">-->
|
||||
<!-- {{ $t("commons.button.bind") }}-->
|
||||
<!-- </el-button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- </el-row>-->
|
||||
<div class="login-container">
|
||||
<el-row type="flex" v-loading="loading">
|
||||
<el-col :span="12">
|
||||
@@ -37,7 +64,6 @@
|
||||
</template>
|
||||
<script>
|
||||
|
||||
|
||||
export default {
|
||||
name: "Login",
|
||||
data () {
|
||||
@@ -68,7 +94,11 @@ export default {
|
||||
redirect: undefined,
|
||||
otherQuery: {},
|
||||
systemName: this.$t("commons.login.title"),
|
||||
loadingPage: false
|
||||
loadingPage: false,
|
||||
otp: {
|
||||
secret: "21121212",
|
||||
qrUrl:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAABlBMVEX///8AAABVwtN+AAACZUlEQVR42uyZP3LmKhDEW0VAyBE4Chd7pT/li3EUjkBIQKlf9SCvPq83t9j9CGSX/EswM909CO/1Xv/kWkjy9EQ4AceDRNyR9DZPBDQAqyewIrGsgS0eNQEIUwGRdfV0FZ6IZCaPmjz74wDA1dXnHlnhyzIp4HMPp2ePRwWwTQjAisnVrcGVrSbri99L7oeB0by5h6MlV9aQrey/dfezgc/Vg9RHi2WrfxDURwNLg23J6Wnd3eIesi/bLaQ/DkB9C1XUiiSALZ4hs7h7KxMA0tBN29yROtZgug+W/66+mAJYWKCWkATlHnegxVOPu3EmAIAIbMysC4f9Nmxk+6VRjwA8O6BUs3u6gkDPU2cxFWDdfSL1sHuLDmjyrC9RbQYg9rBLSCl014+lAvFRAOlUQF2/mQT5YmLU72z/fMDsavdURWVIQ9vwhKkAS0Eb2bE1BSBle9ZXIX0A8Nm8fZzKqRfyLH7cnjUFAChrVqh592AHQj8bUHRiQ4Jgc6DKyt957QHASMWwvEY7EJ0FfXFfYvPDAfii13mIUbGQAyRP3v+HCQDYnAVnY0pkTU0hQi/yYwDzrMPUviWWhVmamVVnmAhgUZ5PuPJkyKOi+HEHzgkAuZO624xBjT1S54tnzQFQE8rID9BgPjr+JSb9OHB1sGX7bJ4FbPVysmmAzzsQyA6ciol2afYyDM4AXLesjodtUzO5bfODTwLGLWu3AylXrCeLmxGwK4Q+/ibjit8vkx8PaKQ9tU0Nt/KE15H2CcBwXvsCIrUfX0Bep8UZgOs7Tg/nSBIJI6/1MBHwXu/1l63/AwAA//8FHjSXDI6EdgAAAABJRU5ErkJggg=="
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -9,27 +9,18 @@
|
||||
<el-form-item :label="$t('business.user.username')" prop="name">
|
||||
<el-input v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('business.user.nickname')" prop="nickname">
|
||||
<el-input v-model="form.nickname"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('business.user.email')" prop="email">
|
||||
<el-input v-model="form.email"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('business.user.password')" prop="password">
|
||||
<el-input type="password" v-model="form.password"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('business.user.confirm_password')" prop="confirmPassword">
|
||||
<el-input type="password" v-model="form.confirmPassword"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('business.user.role')" prop="roles">
|
||||
<el-select v-model="form.roles" multiple filterable
|
||||
style="width: 100%"
|
||||
@@ -42,8 +33,9 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('commons.table.mfa_enable')" prop="mfa.enable">
|
||||
<el-checkbox v-model="form.mfa.enable">{{$t('commons.enable.true')}}</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div style="float: right">
|
||||
<el-button @click="onCancel()">{{ $t("commons.button.cancel") }}</el-button>
|
||||
@@ -51,7 +43,6 @@
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
@@ -116,6 +107,9 @@ export default {
|
||||
roles: [
|
||||
Rules.RequiredRule,
|
||||
],
|
||||
mfa:{
|
||||
// enable:Rules.RequiredRule,
|
||||
}
|
||||
},
|
||||
form: {
|
||||
name: "",
|
||||
@@ -124,6 +118,9 @@ export default {
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
roles: [],
|
||||
mfa: {
|
||||
enbale: false
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -5,21 +5,15 @@
|
||||
<el-col :span="10">
|
||||
<div class="grid-content bg-purple-light">
|
||||
<el-form ref="form" :rules="rules" :model="form" label-width="150px" label-position="left">
|
||||
|
||||
<el-form-item :label="$t('business.user.username')" prop="name">
|
||||
<el-input v-model="form.name" disabled></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('business.user.nickname')" prop="nickname">
|
||||
<el-input v-model="form.nickname" :disabled="form.type ==='LDAP'"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('business.user.email')" prop="email">
|
||||
<el-input v-model="form.email" :disabled="form.type ==='LDAP'"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('business.user.role')" prop="roles">
|
||||
<el-select v-model="form.roles" filterable
|
||||
multiple
|
||||
@@ -33,13 +27,12 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('business.user.password')" v-if="form.type !=='LDAP'">
|
||||
<el-link @click="openedChangePassword">{{ $t("business.user.change_password") }}</el-link>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item :label="$t('commons.table.mfa_enable')" prop="mfa.enable">
|
||||
<el-checkbox v-model="form.mfa.enable">{{$t('commons.enable.true')}}</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div style="float: right">
|
||||
<el-button @click="onCancel()">{{ $t("commons.button.cancel") }}</el-button>
|
||||
@@ -131,6 +124,9 @@ export default {
|
||||
roles: [
|
||||
Rules.RequiredRule,
|
||||
],
|
||||
mfa:{
|
||||
// enable:Rules.RequiredRule,
|
||||
}
|
||||
},
|
||||
changePasswordOpened: false,
|
||||
passwordChangeRules: {
|
||||
@@ -154,7 +150,10 @@ export default {
|
||||
nickname: "",
|
||||
email: "",
|
||||
roles: [],
|
||||
type: "LOCAL"
|
||||
type: "LOCAL",
|
||||
mfa: {
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -26,18 +26,21 @@
|
||||
<el-tag style="margin-left: 5px" size="small" v-if="row.roles.length===0 && row.isAdmin">Supper User</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="$t('business.user.email')" min-width="100" fix>
|
||||
<template v-slot:default="{row}">
|
||||
{{ row.email }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="$t('commons.table.built_in')" min-width="100" fix>
|
||||
<template v-slot:default="{row}">
|
||||
{{ $t("commons.bool." + row.builtIn) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.mfa_enable')" min-width="100" fix>
|
||||
<template v-slot:default="{row}">
|
||||
{{ $t("commons.enable." + row.mfa.enable) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('business.user.type')" min-width="100" fix>
|
||||
<template v-slot:default="{row}">
|
||||
{{ row.type ? row.type : "LOCAL" }}
|
||||
@@ -49,7 +52,6 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<fu-table-operations :buttons="buttons" :label="$t('commons.table.action')"/>
|
||||
</complex-table>
|
||||
</layout-content>
|
||||
@@ -146,7 +148,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.ps.length !== 0) {
|
||||
if (this.ps.length !== 0) {
|
||||
Promise.all(this.ps)
|
||||
.then(() => {
|
||||
this.search()
|
||||
|
||||
@@ -41,7 +41,8 @@ const message = {
|
||||
upload: "Upload",
|
||||
search: "Search",
|
||||
rbac_manage: "RBAC Manage",
|
||||
sync: "Sync"
|
||||
sync: "Sync",
|
||||
bind: "Bind"
|
||||
},
|
||||
table: {
|
||||
name: "Name",
|
||||
@@ -54,6 +55,7 @@ const message = {
|
||||
built_in: "Built in",
|
||||
description: "Description",
|
||||
empty_text: "There are no rows to show.",
|
||||
mfa_enable: "MFA Auth"
|
||||
},
|
||||
header: {
|
||||
help_doc: "document",
|
||||
@@ -65,6 +67,10 @@ const message = {
|
||||
true: "true",
|
||||
false: "false"
|
||||
},
|
||||
enable: {
|
||||
true: "Enable",
|
||||
false: "Disable"
|
||||
},
|
||||
search: {
|
||||
quickSearch: "quick search"
|
||||
},
|
||||
@@ -98,7 +104,8 @@ const message = {
|
||||
password: "password",
|
||||
title: "login KubePi",
|
||||
welcome: "Welcome back, please enter your user name and password to log in",
|
||||
expires: "The authentication information has expired. Please log in again."
|
||||
expires: "The authentication information has expired. Please log in again.",
|
||||
mfa_helper: "Scan the QR code below with the MFA Authenticator app to get a 6-digit verification code",
|
||||
},
|
||||
},
|
||||
business: {
|
||||
|
||||
@@ -41,7 +41,8 @@ const message = {
|
||||
upload: "上传文件",
|
||||
search: "搜索",
|
||||
rbac_manage: "授权",
|
||||
sync: "同步"
|
||||
sync: "同步",
|
||||
bind: "绑定"
|
||||
},
|
||||
table: {
|
||||
name: "名称",
|
||||
@@ -54,6 +55,7 @@ const message = {
|
||||
built_in: "内置",
|
||||
description: "描述",
|
||||
empty_text: "没有内容显示",
|
||||
mfa_enable: "MFA认证"
|
||||
},
|
||||
header: {
|
||||
help_doc: "帮助文档",
|
||||
@@ -65,6 +67,10 @@ const message = {
|
||||
true: "是",
|
||||
false: "否"
|
||||
},
|
||||
enable: {
|
||||
true: "启用",
|
||||
false: "禁用"
|
||||
},
|
||||
search: {
|
||||
quickSearch: "搜索"
|
||||
},
|
||||
@@ -99,6 +105,7 @@ const message = {
|
||||
title: "登录 KubePi",
|
||||
welcome: "欢迎回来,请输入用户名和密码登录",
|
||||
expires: "认证信息已过期,请重新登录",
|
||||
mfa_helper: "使用 MFA 验证器应用扫描以下二维码,获取6位验证码",
|
||||
},
|
||||
},
|
||||
business: {
|
||||
|
||||
@@ -19,12 +19,12 @@ module.exports = {
|
||||
target: 'http://0.0.0.0:4400',
|
||||
},
|
||||
'/kubepi/api': {
|
||||
target: 'http://0.0.0.0:80',
|
||||
target: 'http://0.0.0.0:2019',
|
||||
ws: true,
|
||||
secure: false,
|
||||
},
|
||||
'/webkubectl': {
|
||||
target: 'http://0.0.0.0:80',
|
||||
target: 'http://0.0.0.0:2019',
|
||||
ws: true,
|
||||
secure: false,
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"/kubepi/api/": {
|
||||
"target": "http://localhost:80"
|
||||
"target": "http://localhost:2019"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user