申请ACME证书时可以指定平台用户

This commit is contained in:
GoEdgeLab
2023-04-23 15:01:43 +08:00
parent 9c95dfcc24
commit d943ebf843
9 changed files with 123 additions and 46 deletions

View File

@@ -18,31 +18,6 @@ func (this *CreateAction) Init() {
} }
func (this *CreateAction) RunGet(params struct{}) { func (this *CreateAction) RunGet(params struct{}) {
// 获取所有可用的用户
usersResp, err := this.RPC().ACMEUserRPC().FindAllACMEUsers(this.AdminContext(), &pb.FindAllACMEUsersRequest{
AdminId: this.AdminId(),
UserId: 0,
})
if err != nil {
this.ErrorPage(err)
return
}
userMaps := []maps.Map{}
for _, user := range usersResp.AcmeUsers {
description := user.Description
if len(description) > 0 {
description = "" + description + ""
}
userMaps = append(userMaps, maps.Map{
"id": user.Id,
"description": description,
"email": user.Email,
"providerCode": user.AcmeProviderCode,
})
}
this.Data["users"] = userMaps
// 证书服务商 // 证书服务商
providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{}) providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
if err != nil { if err != nil {
@@ -81,14 +56,15 @@ func (this *CreateAction) RunGet(params struct{}) {
} }
func (this *CreateAction) RunPost(params struct { func (this *CreateAction) RunPost(params struct {
TaskId int64 PlatformUserId int64
AuthType string TaskId int64
AcmeUserId int64 AuthType string
DnsProviderId int64 AcmeUserId int64
DnsDomain string DnsProviderId int64
Domains []string DnsDomain string
AutoRenew bool Domains []string
AuthURL string AutoRenew bool
AuthURL string
Must *actions.Must Must *actions.Must
}) { }) {
@@ -117,7 +93,7 @@ func (this *CreateAction) RunPost(params struct {
if len(params.Domains) == 0 { if len(params.Domains) == 0 {
this.Fail("请输入证书域名列表") this.Fail("请输入证书域名列表")
} }
realDomains := []string{} var realDomains = []string{}
for _, domain := range params.Domains { for _, domain := range params.Domains {
domain = strings.ToLower(domain) domain = strings.ToLower(domain)
if params.AuthType == "dns" { // DNS认证 if params.AuthType == "dns" { // DNS认证
@@ -134,6 +110,7 @@ func (this *CreateAction) RunPost(params struct {
if params.TaskId == 0 { if params.TaskId == 0 {
createResp, err := this.RPC().ACMETaskRPC().CreateACMETask(this.AdminContext(), &pb.CreateACMETaskRequest{ createResp, err := this.RPC().ACMETaskRPC().CreateACMETask(this.AdminContext(), &pb.CreateACMETaskRequest{
UserId: params.PlatformUserId,
AuthType: params.AuthType, AuthType: params.AuthType,
AcmeUserId: params.AcmeUserId, AcmeUserId: params.AcmeUserId,
DnsProviderId: params.DnsProviderId, DnsProviderId: params.DnsProviderId,

View File

@@ -12,6 +12,8 @@ type RunAction struct {
func (this *RunAction) RunPost(params struct { func (this *RunAction) RunPost(params struct {
TaskId int64 TaskId int64
}) { }) {
defer this.CreateLogInfo("执行ACME任务 %d", params.TaskId)
runResp, err := this.RPC().ACMETaskRPC().RunACMETask(this.AdminContext(), &pb.RunACMETaskRequest{AcmeTaskId: params.TaskId}) runResp, err := this.RPC().ACMETaskRPC().RunACMETask(this.AdminContext(), &pb.RunACMETaskRequest{AcmeTaskId: params.TaskId})
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -0,0 +1,44 @@
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package acme
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps"
)
type UserOptionsAction struct {
actionutils.ParentAction
}
func (this *UserOptionsAction) RunPost(params struct {
PlatformUserId int64
}) {
// 获取所有可用的用户
usersResp, err := this.RPC().ACMEUserRPC().FindAllACMEUsers(this.AdminContext(), &pb.FindAllACMEUsersRequest{
AdminId: 0,
UserId: params.PlatformUserId,
})
if err != nil {
this.ErrorPage(err)
return
}
var userMaps = []maps.Map{}
for _, user := range usersResp.AcmeUsers {
description := user.Description
if len(description) > 0 {
description = "" + description + ""
}
userMaps = append(userMaps, maps.Map{
"id": user.Id,
"description": description,
"email": user.Email,
"providerCode": user.AcmeProviderCode,
})
}
this.Data["users"] = userMaps
this.Success()
}

View File

@@ -16,10 +16,30 @@ func (this *CreatePopupAction) Init() {
} }
func (this *CreatePopupAction) RunGet(params struct { func (this *CreatePopupAction) RunGet(params struct {
ProviderCode string PlatformUserId int64
ProviderCode string
}) { }) {
this.Data["platformUserId"] = params.PlatformUserId
this.Data["providerCode"] = params.ProviderCode this.Data["providerCode"] = params.ProviderCode
// 平台用户信息
this.Data["platformUser"] = nil
if params.PlatformUserId > 0 {
platformUserResp, err := this.RPC().UserRPC().FindEnabledUser(this.AdminContext(), &pb.FindEnabledUserRequest{UserId: params.PlatformUserId})
if err != nil {
this.ErrorPage(err)
return
}
var platformUser = platformUserResp.User
if platformUser != nil {
this.Data["platformUser"] = maps.Map{
"id": platformUser.Id,
"username": platformUser.Username,
"fullname": platformUser.Fullname,
}
}
}
// 服务商 // 服务商
providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{}) providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
if err != nil { if err != nil {
@@ -40,10 +60,11 @@ func (this *CreatePopupAction) RunGet(params struct {
} }
func (this *CreatePopupAction) RunPost(params struct { func (this *CreatePopupAction) RunPost(params struct {
Email string PlatformUserId int64
ProviderCode string Email string
AccountId int64 ProviderCode string
Description string AccountId int64
Description string
Must *actions.Must Must *actions.Must
CSRF *actionutils.CSRF CSRF *actionutils.CSRF
@@ -85,6 +106,7 @@ func (this *CreatePopupAction) RunPost(params struct {
} }
createResp, err := this.RPC().ACMEUserRPC().CreateACMEUser(this.AdminContext(), &pb.CreateACMEUserRequest{ createResp, err := this.RPC().ACMEUserRPC().CreateACMEUser(this.AdminContext(), &pb.CreateACMEUserRequest{
UserId: params.PlatformUserId,
Email: params.Email, Email: params.Email,
Description: params.Description, Description: params.Description,
AcmeProviderCode: params.ProviderCode, AcmeProviderCode: params.ProviderCode,

View File

@@ -41,6 +41,7 @@ func init() {
Post("/run", new(acme.RunAction)). Post("/run", new(acme.RunAction)).
GetPost("/updateTaskPopup", new(acme.UpdateTaskPopupAction)). GetPost("/updateTaskPopup", new(acme.UpdateTaskPopupAction)).
Post("/deleteTask", new(acme.DeleteTaskAction)). Post("/deleteTask", new(acme.DeleteTaskAction)).
Post("/userOptions", new(acme.UserOptionsAction)).
// ACME用户 // ACME用户
Prefix("/servers/certs/acme/users"). Prefix("/servers/certs/acme/users").

View File

@@ -26,7 +26,7 @@
<div v-show="step == 'prepare'"> <div v-show="step == 'prepare'">
<table class="ui table definition selectable"> <table class="ui table definition selectable">
<tr> <tr>
<td class="title">认证方式</td> <td class="title">认证方式 *</td>
<td> <td>
<div style="margin-bottom: 1em"> <div style="margin-bottom: 1em">
<radio name="authType" :v-value="'http'" v-model="authType">使用HTTP认证</radio> &nbsp; <radio name="authType" :v-value="'http'" v-model="authType">使用HTTP认证</radio> &nbsp;
@@ -39,6 +39,13 @@
<p class="comment">我们在申请免费证书的过程中需要自动增加或修改相关域名的TXT记录请先确保你已经在"域名解析" -- <a href="/dns/providers" target="_blank">"DNS服务商"</a> 中已经添加了对应的DNS服务商账号。</p> <p class="comment">我们在申请免费证书的过程中需要自动增加或修改相关域名的TXT记录请先确保你已经在"域名解析" -- <a href="/dns/providers" target="_blank">"DNS服务商"</a> 中已经添加了对应的DNS服务商账号。</p>
</div> </div>
</td> </td>
</tr>
<tr>
<td>选择平台用户</td>
<td>
<user-selector @change="changePlatformUser"></user-selector>
<p class="comment">可选项,选择证书所属用户,如果没有选择,则视为管理员所有。</p>
</td>
</tr> </tr>
<tr> <tr>
<td colspan="2"> <td colspan="2">
@@ -74,7 +81,7 @@
</td> </td>
</tr> </tr>
<tr v-if="providerCode.length > 0"> <tr v-if="providerCode.length > 0">
<td class="title">选择用户 *</td> <td class="title">选择ACME用户 *</td>
<td> <td>
<div v-if="users.length > 0"> <div v-if="users.length > 0">
<div class="ui fields inline"> <div class="ui fields inline">
@@ -89,7 +96,7 @@
</div> </div>
</div> </div>
</div> </div>
<div v-else><a href="" @click.prevent="createUser">暂时还没有用户,点此创建</a></div> <div v-else><a href="" @click.prevent="createUser"><span v-if="platformUserId > 0">当前平台用户下</span>暂时还没有ACME用户,点此创建</a></div>
<p class="comment">选择一个作为申请证书的用户。</p> <p class="comment">选择一个作为申请证书的用户。</p>
</td> </td>
</tr> </tr>

View File

@@ -1,13 +1,31 @@
Tea.context(function () { Tea.context(function () {
this.step = "prepare" this.step = "prepare"
/**
* 选择平台用户
*/
this.platformUserId = 0
this.changePlatformUser = function (platformUserId) {
this.platformUserId = platformUserId
}
/** /**
* 准备工作 * 准备工作
*/ */
this.authType = "http" this.authType = "http"
this.users = []
this.doPrepare = function () { this.doPrepare = function () {
this.step = "user" this.step = "user"
this.$post(".userOptions")
.params({
platformUserId: this.platformUserId
})
.success(function (resp) {
this.users = resp.data.users
})
} }
this.prepareMoreOptionsVisible = false this.prepareMoreOptionsVisible = false
@@ -17,7 +35,7 @@ Tea.context(function () {
} }
/** /**
* 选择用户 * 选择ACME用户
*/ */
this.userId = 0 this.userId = 0
@@ -27,7 +45,7 @@ Tea.context(function () {
this.createUser = function () { this.createUser = function () {
let that = this let that = this
teaweb.popup("/servers/certs/acme/users/createPopup?providerCode=" + this.providerCode, { teaweb.popup("/servers/certs/acme/users/createPopup?providerCode=" + this.providerCode + "&platformUserId=" + this.platformUserId, {
height: "30em", height: "30em",
width: "44em", width: "44em",
callback: function (resp) { callback: function (resp) {
@@ -90,6 +108,7 @@ Tea.context(function () {
this.$post("$") this.$post("$")
.params({ .params({
platformUserId: this.platformUserId,
authType: this.authType, authType: this.authType,
acmeUserId: this.userId, acmeUserId: this.userId,
dnsProviderId: this.dnsProviderId, dnsProviderId: this.dnsProviderId,

View File

@@ -1,9 +1,14 @@
{$layout "layout_popup"} {$layout "layout_popup"}
<h3>创建用户</h3> <h3>创建ACME用户</h3>
<form method="post" class="ui form" data-tea-success="success" data-tea-action="$"> <form method="post" class="ui form" data-tea-success="success" data-tea-action="$">
<csrf-token></csrf-token> <csrf-token></csrf-token>
<input type="hidden" name="platformUserId" :value="platformUserId"/>
<table class="ui table definition selectable"> <table class="ui table definition selectable">
<tr v-if="platformUser != null">
<td>所属平台用户</td>
<td><user-link :v-user="platformUser"></user-link></td>
</tr>
<tr> <tr>
<td class="title">用户邮箱 *</td> <td class="title">用户邮箱 *</td>
<td> <td>

View File

@@ -1,6 +1,6 @@
{$layout "layout_popup"} {$layout "layout_popup"}
<h3>修改用户</h3> <h3>修改ACME用户</h3>
<form method="post" class="ui form" data-tea-success="success" data-tea-action="$"> <form method="post" class="ui form" data-tea-success="success" data-tea-action="$">
<csrf-token></csrf-token> <csrf-token></csrf-token>
<input type="hidden" name="userId" :value="user.id"/> <input type="hidden" name="userId" :value="user.id"/>