[SSL证书]实现对ACME任务的增删改查

This commit is contained in:
刘祥超
2020-11-25 21:19:22 +08:00
parent 6e6083d6af
commit 4142fae762
22 changed files with 862 additions and 180 deletions

View File

@@ -0,0 +1,281 @@
package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// ACME任务相关服务
type ACMETaskService struct {
BaseService
}
// 计算某个ACME用户相关的任务数量
func (this *ACMETaskService) CountAllEnabledACMETasksWithACMEUserId(ctx context.Context, req *pb.CountAllEnabledACMETasksWithACMEUserIdRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
// TODO 校验权限
count, err := models.SharedACMETaskDAO.CountACMETasksWithACMEUserId(req.AcmeUserId)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// 计算跟某个DNS服务商相关的任务数量
func (this *ACMETaskService) CountEnabledACMETasksWithDNSProviderId(ctx context.Context, req *pb.CountEnabledACMETasksWithDNSProviderIdRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
// TODO 校验权限
count, err := models.SharedACMETaskDAO.CountACMETasksWithDNSProviderId(req.DnsProviderId)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// 计算所有任务数量
func (this *ACMETaskService) CountAllEnabledACMETasks(ctx context.Context, req *pb.CountAllEnabledACMETasksRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, req.UserId)
if err != nil {
return nil, err
}
count, err := models.SharedACMETaskDAO.CountAllEnabledACMETasks(req.AdminId, req.UserId)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// 列出单页任务
func (this *ACMETaskService) ListEnabledACMETasks(ctx context.Context, req *pb.ListEnabledACMETasksRequest) (*pb.ListEnabledACMETasksResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, req.UserId)
if err != nil {
return nil, err
}
tasks, err := models.SharedACMETaskDAO.ListEnabledACMETasks(req.AdminId, req.UserId, req.Offset, req.Size)
if err != nil {
return nil, err
}
result := []*pb.ACMETask{}
for _, task := range tasks {
// ACME用户
acmeUser, err := models.SharedACMEUserDAO.FindEnabledACMEUser(int64(task.AcmeUserId))
if err != nil {
return nil, err
}
if acmeUser == nil {
continue
}
pbACMEUser := &pb.ACMEUser{
Id: int64(acmeUser.Id),
Email: acmeUser.Email,
Description: acmeUser.Description,
CreatedAt: int64(acmeUser.CreatedAt),
}
// DNS
provider, err := models.SharedDNSProviderDAO.FindEnabledDNSProvider(int64(task.DnsProviderId))
if err != nil {
return nil, err
}
if provider == nil {
continue
}
pbProvider := &pb.DNSProvider{
Id: int64(provider.Id),
Name: provider.Name,
Type: provider.Type,
TypeName: dnsclients.FindProviderTypeName(provider.Type),
}
// 证书
var pbCert *pb.SSLCert = nil
if task.CertId > 0 {
cert, err := models.SharedSSLCertDAO.FindEnabledSSLCert(int64(task.CertId))
if err != nil {
return nil, err
}
if cert == nil {
continue
}
pbCert = &pb.SSLCert{
Id: int64(cert.Id),
IsOn: cert.IsOn == 1,
Name: cert.Name,
}
}
result = append(result, &pb.ACMETask{
Id: int64(task.Id),
IsOn: task.IsOn == 1,
DnsDomain: task.DnsDomain,
Domains: task.DecodeDomains(),
CreatedAt: int64(task.CreatedAt),
IsOk: task.IsOk == 1,
AutoRenew: task.AutoRenew == 1,
AcmeUser: pbACMEUser,
DnsProvider: pbProvider,
SslCert: pbCert,
})
}
return &pb.ListEnabledACMETasksResponse{AcmeTasks: result}, nil
}
// 创建任务
func (this *ACMETaskService) CreateACMETask(ctx context.Context, req *pb.CreateACMETaskRequest) (*pb.CreateACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
taskId, err := models.SharedACMETaskDAO.CreateACMETask(adminId, userId, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew)
if err != nil {
return nil, err
}
return &pb.CreateACMETaskResponse{AcmeTaskId: taskId}, nil
}
// 修改任务
func (this *ACMETaskService) UpdateACMETask(ctx context.Context, req *pb.UpdateACMETaskRequest) (*pb.RPCSuccess, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
canAccess, err := models.SharedACMETaskDAO.CheckACMETask(adminId, userId, req.AcmeTaskId)
if err != nil {
return nil, err
}
if !canAccess {
return nil, this.PermissionError()
}
err = models.SharedACMETaskDAO.UpdateACMETask(req.AcmeTaskId, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew)
if err != nil {
return nil, err
}
return this.Success()
}
// 删除任务
func (this *ACMETaskService) DeleteACMETask(ctx context.Context, req *pb.DeleteACMETaskRequest) (*pb.RPCSuccess, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
canAccess, err := models.SharedACMETaskDAO.CheckACMETask(adminId, userId, req.AcmeTaskId)
if err != nil {
return nil, err
}
if !canAccess {
return nil, this.PermissionError()
}
err = models.SharedACMETaskDAO.DisableACMETask(req.AcmeTaskId)
if err != nil {
return nil, err
}
return this.Success()
}
// 运行某个任务
func (this *ACMETaskService) RunACMETask(ctx context.Context, req *pb.RunACMETaskRequest) (*pb.RunACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
canAccess, err := models.SharedACMETaskDAO.CheckACMETask(adminId, userId, req.AcmeTaskId)
if err != nil {
return nil, err
}
if !canAccess {
return nil, this.PermissionError()
}
// TODO
return &pb.RunACMETaskResponse{}, nil
}
// 查找单个任务信息
func (this *ACMETaskService) FindEnabledACMETask(ctx context.Context, req *pb.FindEnabledACMETaskRequest) (*pb.FindEnabledACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
canAccess, err := models.SharedACMETaskDAO.CheckACMETask(adminId, userId, req.AcmeTaskId)
if err != nil {
return nil, err
}
if !canAccess {
return nil, this.PermissionError()
}
task, err := models.SharedACMETaskDAO.FindEnabledACMETask(req.AcmeTaskId)
if err != nil {
return nil, err
}
if task == nil {
return &pb.FindEnabledACMETaskResponse{AcmeTask: nil}, nil
}
// 用户
var pbACMEUser *pb.ACMEUser = nil
if task.AcmeUserId > 0 {
acmeUser, err := models.SharedACMEUserDAO.FindEnabledACMEUser(int64(task.AcmeUserId))
if err != nil {
return nil, err
}
if acmeUser != nil {
pbACMEUser = &pb.ACMEUser{
Id: int64(acmeUser.Id),
Email: acmeUser.Email,
Description: acmeUser.Description,
CreatedAt: int64(acmeUser.CreatedAt),
}
}
}
// DNS
var pbProvider *pb.DNSProvider
provider, err := models.SharedDNSProviderDAO.FindEnabledDNSProvider(int64(task.DnsProviderId))
if err != nil {
return nil, err
}
if provider != nil {
pbProvider = &pb.DNSProvider{
Id: int64(provider.Id),
Name: provider.Name,
Type: provider.Type,
TypeName: dnsclients.FindProviderTypeName(provider.Type),
}
}
return &pb.FindEnabledACMETaskResponse{AcmeTask: &pb.ACMETask{
Id: int64(task.Id),
IsOn: task.IsOn == 1,
DnsDomain: task.DnsDomain,
Domains: task.DecodeDomains(),
CreatedAt: int64(task.CreatedAt),
AutoRenew: task.AutoRenew == 1,
DnsProvider: pbProvider,
AcmeUser: pbACMEUser,
}}, nil
}

View File

@@ -14,7 +14,7 @@ type ACMEUserService struct {
// 创建用户
func (this *ACMEUserService) CreateACMEUser(ctx context.Context, req *pb.CreateACMEUserRequest) (*pb.CreateACMEUserResponse, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx)
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
@@ -29,7 +29,7 @@ func (this *ACMEUserService) CreateACMEUser(ctx context.Context, req *pb.CreateA
// 修改用户
func (this *ACMEUserService) UpdateACMEUser(ctx context.Context, req *pb.UpdateACMEUserRequest) (*pb.RPCSuccess, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx)
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
@@ -53,7 +53,7 @@ func (this *ACMEUserService) UpdateACMEUser(ctx context.Context, req *pb.UpdateA
// 删除用户
func (this *ACMEUserService) DeleteACMEUser(ctx context.Context, req *pb.DeleteACMEUserRequest) (*pb.RPCSuccess, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx)
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
@@ -77,7 +77,7 @@ func (this *ACMEUserService) DeleteACMEUser(ctx context.Context, req *pb.DeleteA
// 计算用户数量
func (this *ACMEUserService) CountACMEUsers(ctx context.Context, req *pb.CountAcmeUsersRequest) (*pb.RPCCountResponse, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx)
adminId, userId, err := this.ValidateAdminAndUser(ctx, req.UserId)
if err != nil {
return nil, err
}
@@ -92,7 +92,7 @@ func (this *ACMEUserService) CountACMEUsers(ctx context.Context, req *pb.CountAc
// 列出单页用户
func (this *ACMEUserService) ListACMEUsers(ctx context.Context, req *pb.ListACMEUsersRequest) (*pb.ListACMEUsersResponse, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx)
adminId, userId, err := this.ValidateAdminAndUser(ctx, req.UserId)
if err != nil {
return nil, err
}
@@ -116,7 +116,7 @@ func (this *ACMEUserService) ListACMEUsers(ctx context.Context, req *pb.ListACME
// 查找单个用户
func (this *ACMEUserService) FindEnabledACMEUser(ctx context.Context, req *pb.FindEnabledACMEUserRequest) (*pb.FindEnabledACMEUserResponse, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx)
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
@@ -144,3 +144,27 @@ func (this *ACMEUserService) FindEnabledACMEUser(ctx context.Context, req *pb.Fi
CreatedAt: int64(acmeUser.CreatedAt),
}}, nil
}
// 查找所有用户
func (this *ACMEUserService) FindAllACMEUsers(ctx context.Context, req *pb.FindAllACMEUsersRequest) (*pb.FindAllACMEUsersResponse, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx, req.UserId)
if err != nil {
return nil, err
}
acmeUsers, err := models.SharedACMEUserDAO.FindAllACMEUsers(adminId, userId)
if err != nil {
return nil, err
}
result := []*pb.ACMEUser{}
for _, user := range acmeUsers {
result = append(result, &pb.ACMEUser{
Id: int64(user.Id),
Email: user.Email,
Description: user.Description,
CreatedAt: int64(user.CreatedAt),
})
}
return &pb.FindAllACMEUsersResponse{AcmeUsers: result}, nil
}

View File

@@ -11,7 +11,7 @@ type BaseService struct {
}
// 校验管理员和用户
func (this *BaseService) ValidateAdminAndUser(ctx context.Context) (adminId int64, userId int64, err error) {
func (this *BaseService) ValidateAdminAndUser(ctx context.Context, reqUserId int64) (adminId int64, userId int64, err error) {
reqUserType, reqUserId, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser)
if err != nil {
return
@@ -22,9 +22,26 @@ func (this *BaseService) ValidateAdminAndUser(ctx context.Context) (adminId int6
switch reqUserType {
case rpcutils.UserTypeAdmin:
adminId = reqUserId
if adminId <= 0 {
err = errors.New("invalid 'adminId'")
return
}
case rpcutils.UserTypeUser:
userId = reqUserId
if userId <= 0 {
err = errors.New("invalid 'userId'")
return
}
// 校验权限
if reqUserId > 0 && reqUserId != userId {
err = this.PermissionError()
return
}
default:
err = errors.New("invalid user type")
}
return
}

View File

@@ -16,12 +16,12 @@ type DNSProviderService struct {
// 创建服务商
func (this *DNSProviderService) CreateDNSProvider(ctx context.Context, req *pb.CreateDNSProviderRequest) (*pb.CreateDNSProviderResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
providerId, err := models.SharedDNSProviderDAO.CreateDNSProvider(req.Type, req.Name, req.ApiParamsJSON)
providerId, err := models.SharedDNSProviderDAO.CreateDNSProvider(adminId, userId, req.Type, req.Name, req.ApiParamsJSON)
if err != nil {
return nil, err
}
@@ -32,11 +32,13 @@ func (this *DNSProviderService) CreateDNSProvider(ctx context.Context, req *pb.C
// 修改服务商
func (this *DNSProviderService) UpdateDNSProvider(ctx context.Context, req *pb.UpdateDNSProviderRequest) (*pb.RPCSuccess, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
_, _, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
// TODO 校验权限
err = models.SharedDNSProviderDAO.UpdateDNSProvider(req.DnsProviderId, req.Name, req.ApiParamsJSON)
if err != nil {
return nil, err
@@ -47,12 +49,12 @@ func (this *DNSProviderService) UpdateDNSProvider(ctx context.Context, req *pb.U
// 计算服务商数量
func (this *DNSProviderService) CountAllEnabledDNSProviders(ctx context.Context, req *pb.CountAllEnabledDNSProvidersRequest) (*pb.RPCCountResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
_, _, err := this.ValidateAdminAndUser(ctx, req.UserId)
if err != nil {
return nil, err
}
count, err := models.SharedDNSProviderDAO.CountAllEnabledDNSProviders()
count, err := models.SharedDNSProviderDAO.CountAllEnabledDNSProviders(req.AdminId, req.UserId)
if err != nil {
return nil, err
}
@@ -62,12 +64,14 @@ func (this *DNSProviderService) CountAllEnabledDNSProviders(ctx context.Context,
// 列出单页服务商信息
func (this *DNSProviderService) ListEnabledDNSProviders(ctx context.Context, req *pb.ListEnabledDNSProvidersRequest) (*pb.ListEnabledDNSProvidersResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
_, _, err := this.ValidateAdminAndUser(ctx, req.UserId)
if err != nil {
return nil, err
}
providers, err := models.SharedDNSProviderDAO.ListEnabledDNSProviders(req.Offset, req.Size)
// TODO 校验权限
providers, err := models.SharedDNSProviderDAO.ListEnabledDNSProviders(req.AdminId, req.UserId, req.Offset, req.Size)
if err != nil {
return nil, err
}
@@ -85,14 +89,44 @@ func (this *DNSProviderService) ListEnabledDNSProviders(ctx context.Context, req
return &pb.ListEnabledDNSProvidersResponse{DnsProviders: result}, nil
}
// 删除服务商
func (this *DNSProviderService) DeleteDNSProvider(ctx context.Context, req *pb.DeleteDNSProviderRequest) (*pb.RPCSuccess, error) {
// 查找所有的DNS服务商
func (this *DNSProviderService) FindAllEnabledDNSProviders(ctx context.Context, req *pb.FindAllEnabledDNSProvidersRequest) (*pb.FindAllEnabledDNSProvidersResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
_, _, err := this.ValidateAdminAndUser(ctx, req.UserId)
if err != nil {
return nil, err
}
// TODO 校验权限
providers, err := models.SharedDNSProviderDAO.FindAllEnabledDNSProviders(req.AdminId, req.UserId)
if err != nil {
return nil, err
}
result := []*pb.DNSProvider{}
for _, provider := range providers {
result = append(result, &pb.DNSProvider{
Id: int64(provider.Id),
Name: provider.Name,
Type: provider.Type,
TypeName: dnsclients.FindProviderTypeName(provider.Type),
ApiParamsJSON: []byte(provider.ApiParams),
DataUpdatedAt: int64(provider.DataUpdatedAt),
})
}
return &pb.FindAllEnabledDNSProvidersResponse{DnsProviders: result}, nil
}
// 删除服务商
func (this *DNSProviderService) DeleteDNSProvider(ctx context.Context, req *pb.DeleteDNSProviderRequest) (*pb.RPCSuccess, error) {
// 校验请求
_, _, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
// TODO 校验权限
err = models.SharedDNSProviderDAO.DisableDNSProvider(req.DnsProviderId)
if err != nil {
return nil, err

View File

@@ -17,11 +17,13 @@ type SSLCertService struct {
// 创建Cert
func (this *SSLCertService) CreateSSLCert(ctx context.Context, req *pb.CreateSSLCertRequest) (*pb.CreateSSLCertResponse, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx)
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0)
if err != nil {
return nil, err
}
// TODO 校验权限
certId, err := models.SharedSSLCertDAO.CreateCert(adminId, userId, req.IsOn, req.Name, req.Description, req.ServerName, req.IsCA, req.CertData, req.KeyData, req.TimeBeginAt, req.TimeEndAt, req.DnsNames, req.CommonNames)
if err != nil {
return nil, err
@@ -79,6 +81,12 @@ func (this *SSLCertService) DeleteSSLCert(ctx context.Context, req *pb.DeleteSSL
return nil, err
}
// 停止相关ACME任务
err = models.SharedACMETaskDAO.DisableAllTasksWithCertId(req.CertId)
if err != nil {
return nil, err
}
return this.Success()
}
@@ -130,72 +138,3 @@ func (this *SSLCertService) ListSSLCerts(ctx context.Context, req *pb.ListSSLCer
}
return &pb.ListSSLCertsResponse{CertsJSON: certConfigsJSON}, nil
}
// 计算某个ACME用户生成的证书数量
func (this *SSLCertService) CountSSLCertsWithACMEUserId(ctx context.Context, req *pb.CountSSLCertsWithACMEUserIdRequest) (*pb.RPCCountResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
if err != nil {
return nil, err
}
// TODO 检查用户权限
count, err := models.SharedSSLCertDAO.CountSSLCertsWithACMEUserId(req.AcmeUserId)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// 计算所有某个管理员/用户下所有的ACME用户生成的证书
func (this *SSLCertService) CountAllSSLCertsWithACME(ctx context.Context, req *pb.CountAllSSLCertsWithACMERequest) (*pb.RPCCountResponse, error) {
// 校验请求
_, _, err := this.ValidateAdminAndUser(ctx)
if err != nil {
return nil, err
}
// TODO 校验用户
count, err := models.SharedSSLCertDAO.CountAllSSLCertsWithACME(req.AdminId, req.UserId)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// 列出单个管理员/用户下所有的ACME用户生成的证书
func (this *SSLCertService) ListSSLCertsWithACME(ctx context.Context, req *pb.ListSSLCertsWithACMERequest) (*pb.ListSSLCertsWithACMEResponse, error) {
// 校验请求
_, _, err := this.ValidateAdminAndUser(ctx)
if err != nil {
return nil, err
}
// TODO 校验用户
certIds, err := models.SharedSSLCertDAO.ListSSLCertIdsWithACME(req.AdminId, req.UserId, req.Offset, req.Size)
if err != nil {
return nil, err
}
certConfigs := []*sslconfigs.SSLCertConfig{}
for _, certId := range certIds {
certConfig, err := models.SharedSSLCertDAO.ComposeCertConfig(certId)
if err != nil {
return nil, err
}
// 这里不需要数据内容
certConfig.CertData = nil
certConfig.KeyData = nil
certConfigs = append(certConfigs, certConfig)
}
certConfigsJSON, err := json.Marshal(certConfigs)
if err != nil {
return nil, err
}
return &pb.ListSSLCertsWithACMEResponse{CertsJSON: certConfigsJSON}, nil
}