diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go index f8e06c83..0bb6b5fb 100644 --- a/internal/rpc/rpc_client.go +++ b/internal/rpc/rpc_client.go @@ -16,56 +16,18 @@ import ( "time" ) +// RPC客户端 type RPCClient struct { - apiConfig *configs.APIConfig - adminClients []pb.AdminServiceClient - nodeClients []pb.NodeServiceClient - nodeGrantClients []pb.NodeGrantServiceClient - nodeClusterClients []pb.NodeClusterServiceClient - nodeIPAddressClients []pb.NodeIPAddressServiceClient - serverClients []pb.ServerServiceClient - apiNodeClients []pb.APINodeServiceClient - originClients []pb.OriginServiceClient - httpWebClients []pb.HTTPWebServiceClient - reverseProxyClients []pb.ReverseProxyServiceClient - httpGzipClients []pb.HTTPGzipServiceClient - httpHeaderPolicyClients []pb.HTTPHeaderPolicyServiceClient - httpHeaderClients []pb.HTTPHeaderServiceClient - httpPageClients []pb.HTTPPageServiceClient - httpAccessLogPolicyClients []pb.HTTPAccessLogPolicyServiceClient - httpCachePolicyClients []pb.HTTPCachePolicyServiceClient - httpFirewallPolicyClients []pb.HTTPFirewallPolicyServiceClient - httpLocationClients []pb.HTTPLocationServiceClient - httpWebsocketClients []pb.HTTPWebsocketServiceClient - httpRewriteRuleClients []pb.HTTPRewriteRuleServiceClient + apiConfig *configs.APIConfig + conns []*grpc.ClientConn } +// 构造新的RPC客户端 func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { if apiConfig == nil { return nil, errors.New("api config should not be nil") } - adminClients := []pb.AdminServiceClient{} - nodeClients := []pb.NodeServiceClient{} - nodeGrantClients := []pb.NodeGrantServiceClient{} - nodeClusterClients := []pb.NodeClusterServiceClient{} - nodeIPAddressClients := []pb.NodeIPAddressServiceClient{} - serverClients := []pb.ServerServiceClient{} - apiNodeClients := []pb.APINodeServiceClient{} - originClients := []pb.OriginServiceClient{} - httpWebClients := []pb.HTTPWebServiceClient{} - reverseProxyClients := []pb.ReverseProxyServiceClient{} - httpGzipClients := []pb.HTTPGzipServiceClient{} - httpHeaderPolicyClients := []pb.HTTPHeaderPolicyServiceClient{} - httpHeaderClients := []pb.HTTPHeaderServiceClient{} - httpPageClients := []pb.HTTPPageServiceClient{} - httpAccessLogPolicyClients := []pb.HTTPAccessLogPolicyServiceClient{} - httpCachePolicyClients := []pb.HTTPCachePolicyServiceClient{} - httpFirewallPolicyClients := []pb.HTTPFirewallPolicyServiceClient{} - httpLocationClients := []pb.HTTPLocationServiceClient{} - httpWebsocketClients := []pb.HTTPWebsocketServiceClient{} - httpRewriteRuleClients := []pb.HTTPRewriteRuleServiceClient{} - conns := []*grpc.ClientConn{} for _, endpoint := range apiConfig.RPC.Endpoints { conn, err := grpc.Dial(endpoint, grpc.WithInsecure()) @@ -78,195 +40,97 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { return nil, errors.New("[RPC]no available endpoints") } - // node clients - for _, conn := range conns { - adminClients = append(adminClients, pb.NewAdminServiceClient(conn)) - nodeClients = append(nodeClients, pb.NewNodeServiceClient(conn)) - nodeGrantClients = append(nodeGrantClients, pb.NewNodeGrantServiceClient(conn)) - nodeClusterClients = append(nodeClusterClients, pb.NewNodeClusterServiceClient(conn)) - nodeIPAddressClients = append(nodeIPAddressClients, pb.NewNodeIPAddressServiceClient(conn)) - serverClients = append(serverClients, pb.NewServerServiceClient(conn)) - apiNodeClients = append(apiNodeClients, pb.NewAPINodeServiceClient(conn)) - originClients = append(originClients, pb.NewOriginServiceClient(conn)) - httpWebClients = append(httpWebClients, pb.NewHTTPWebServiceClient(conn)) - reverseProxyClients = append(reverseProxyClients, pb.NewReverseProxyServiceClient(conn)) - httpGzipClients = append(httpGzipClients, pb.NewHTTPGzipServiceClient(conn)) - httpHeaderPolicyClients = append(httpHeaderPolicyClients, pb.NewHTTPHeaderPolicyServiceClient(conn)) - httpHeaderClients = append(httpHeaderClients, pb.NewHTTPHeaderServiceClient(conn)) - httpPageClients = append(httpPageClients, pb.NewHTTPPageServiceClient(conn)) - httpAccessLogPolicyClients = append(httpAccessLogPolicyClients, pb.NewHTTPAccessLogPolicyServiceClient(conn)) - httpCachePolicyClients = append(httpCachePolicyClients, pb.NewHTTPCachePolicyServiceClient(conn)) - httpFirewallPolicyClients = append(httpFirewallPolicyClients, pb.NewHTTPFirewallPolicyServiceClient(conn)) - httpLocationClients = append(httpLocationClients, pb.NewHTTPLocationServiceClient(conn)) - httpWebsocketClients = append(httpWebsocketClients, pb.NewHTTPWebsocketServiceClient(conn)) - httpRewriteRuleClients = append(httpRewriteRuleClients, pb.NewHTTPRewriteRuleServiceClient(conn)) - } - return &RPCClient{ - apiConfig: apiConfig, - adminClients: adminClients, - nodeClients: nodeClients, - nodeGrantClients: nodeGrantClients, - nodeClusterClients: nodeClusterClients, - nodeIPAddressClients: nodeIPAddressClients, - serverClients: serverClients, - apiNodeClients: apiNodeClients, - originClients: originClients, - httpWebClients: httpWebClients, - reverseProxyClients: reverseProxyClients, - httpGzipClients: httpGzipClients, - httpHeaderPolicyClients: httpHeaderPolicyClients, - httpHeaderClients: httpHeaderClients, - httpPageClients: httpPageClients, - httpAccessLogPolicyClients: httpAccessLogPolicyClients, - httpCachePolicyClients: httpCachePolicyClients, - httpFirewallPolicyClients: httpFirewallPolicyClients, - httpLocationClients: httpLocationClients, - httpWebsocketClients: httpWebsocketClients, - httpRewriteRuleClients: httpRewriteRuleClients, + apiConfig: apiConfig, + conns: conns, }, nil } func (this *RPCClient) AdminRPC() pb.AdminServiceClient { - if len(this.adminClients) > 0 { - return this.adminClients[rands.Int(0, len(this.adminClients)-1)] - } - return nil + return pb.NewAdminServiceClient(this.pickConn()) } func (this *RPCClient) NodeRPC() pb.NodeServiceClient { - if len(this.nodeClients) > 0 { - return this.nodeClients[rands.Int(0, len(this.nodeClients)-1)] - } - return nil + return pb.NewNodeServiceClient(this.pickConn()) } func (this *RPCClient) NodeGrantRPC() pb.NodeGrantServiceClient { - if len(this.nodeGrantClients) > 0 { - return this.nodeGrantClients[rands.Int(0, len(this.nodeGrantClients)-1)] - } - return nil + return pb.NewNodeGrantServiceClient(this.pickConn()) } func (this *RPCClient) NodeClusterRPC() pb.NodeClusterServiceClient { - if len(this.nodeClusterClients) > 0 { - return this.nodeClusterClients[rands.Int(0, len(this.nodeClusterClients)-1)] - } - return nil + return pb.NewNodeClusterServiceClient(this.pickConn()) } func (this *RPCClient) NodeIPAddressRPC() pb.NodeIPAddressServiceClient { - if len(this.nodeIPAddressClients) > 0 { - return this.nodeIPAddressClients[rands.Int(0, len(this.nodeIPAddressClients)-1)] - } - return nil + return pb.NewNodeIPAddressServiceClient(this.pickConn()) } func (this *RPCClient) ServerRPC() pb.ServerServiceClient { - if len(this.serverClients) > 0 { - return this.serverClients[rands.Int(0, len(this.serverClients)-1)] - } - return nil + return pb.NewServerServiceClient(this.pickConn()) } func (this *RPCClient) APINodeRPC() pb.APINodeServiceClient { - if len(this.apiNodeClients) > 0 { - return this.apiNodeClients[rands.Int(0, len(this.apiNodeClients)-1)] - } - return nil + return pb.NewAPINodeServiceClient(this.pickConn()) } func (this *RPCClient) OriginRPC() pb.OriginServiceClient { - if len(this.originClients) > 0 { - return this.originClients[rands.Int(0, len(this.originClients)-1)] - } - return nil + return pb.NewOriginServiceClient(this.pickConn()) } func (this *RPCClient) HTTPWebRPC() pb.HTTPWebServiceClient { - if len(this.httpWebClients) > 0 { - return this.httpWebClients[rands.Int(0, len(this.httpWebClients)-1)] - } - return nil + return pb.NewHTTPWebServiceClient(this.pickConn()) } func (this *RPCClient) ReverseProxyRPC() pb.ReverseProxyServiceClient { - if len(this.reverseProxyClients) > 0 { - return this.reverseProxyClients[rands.Int(0, len(this.reverseProxyClients)-1)] - } - return nil + return pb.NewReverseProxyServiceClient(this.pickConn()) } func (this *RPCClient) HTTPGzipRPC() pb.HTTPGzipServiceClient { - if len(this.httpGzipClients) > 0 { - return this.httpGzipClients[rands.Int(0, len(this.httpGzipClients)-1)] - } - return nil + return pb.NewHTTPGzipServiceClient(this.pickConn()) } func (this *RPCClient) HTTPHeaderRPC() pb.HTTPHeaderServiceClient { - if len(this.httpHeaderClients) > 0 { - return this.httpHeaderClients[rands.Int(0, len(this.httpHeaderClients)-1)] - } - return nil + return pb.NewHTTPHeaderServiceClient(this.pickConn()) } func (this *RPCClient) HTTPHeaderPolicyRPC() pb.HTTPHeaderPolicyServiceClient { - if len(this.httpHeaderPolicyClients) > 0 { - return this.httpHeaderPolicyClients[rands.Int(0, len(this.httpHeaderPolicyClients)-1)] - } - return nil + return pb.NewHTTPHeaderPolicyServiceClient(this.pickConn()) } func (this *RPCClient) HTTPPageRPC() pb.HTTPPageServiceClient { - if len(this.httpPageClients) > 0 { - return this.httpPageClients[rands.Int(0, len(this.httpPageClients)-1)] - } - return nil + return pb.NewHTTPPageServiceClient(this.pickConn()) } func (this *RPCClient) HTTPAccessLogPolicyRPC() pb.HTTPAccessLogPolicyServiceClient { - if len(this.httpAccessLogPolicyClients) > 0 { - return this.httpAccessLogPolicyClients[rands.Int(0, len(this.httpAccessLogPolicyClients)-1)] - } - return nil + return pb.NewHTTPAccessLogPolicyServiceClient(this.pickConn()) } func (this *RPCClient) HTTPCachePolicyRPC() pb.HTTPCachePolicyServiceClient { - if len(this.httpCachePolicyClients) > 0 { - return this.httpCachePolicyClients[rands.Int(0, len(this.httpCachePolicyClients)-1)] - } - return nil + return pb.NewHTTPCachePolicyServiceClient(this.pickConn()) } func (this *RPCClient) HTTPFirewallPolicyRPC() pb.HTTPFirewallPolicyServiceClient { - if len(this.httpFirewallPolicyClients) > 0 { - return this.httpFirewallPolicyClients[rands.Int(0, len(this.httpFirewallPolicyClients)-1)] - } - return nil + return pb.NewHTTPFirewallPolicyServiceClient(this.pickConn()) } func (this *RPCClient) HTTPLocationRPC() pb.HTTPLocationServiceClient { - if len(this.httpLocationClients) > 0 { - return this.httpLocationClients[rands.Int(0, len(this.httpLocationClients)-1)] - } - return nil + return pb.NewHTTPLocationServiceClient(this.pickConn()) } func (this *RPCClient) HTTPWebsocketRPC() pb.HTTPWebsocketServiceClient { - if len(this.httpWebsocketClients) > 0 { - return this.httpWebsocketClients[rands.Int(0, len(this.httpWebsocketClients)-1)] - } - return nil + return pb.NewHTTPWebsocketServiceClient(this.pickConn()) } func (this *RPCClient) HTTPRewriteRuleRPC() pb.HTTPRewriteRuleServiceClient { - if len(this.httpRewriteRuleClients) > 0 { - return this.httpRewriteRuleClients[rands.Int(0, len(this.httpRewriteRuleClients)-1)] - } - return nil + return pb.NewHTTPRewriteRuleServiceClient(this.pickConn()) } +func (this *RPCClient) SSLCertRPC() pb.SSLCertServiceClient { + return pb.NewSSLCertServiceClient(this.pickConn()) +} + +// 构造上下文 func (this *RPCClient) Context(adminId int64) context.Context { ctx := context.Background() m := maps.Map{ @@ -288,3 +152,11 @@ func (this *RPCClient) Context(adminId int64) context.Context { ctx = metadata.AppendToOutgoingContext(ctx, "nodeId", this.apiConfig.NodeId, "token", token) return ctx } + +// 随机选择一个连接 +func (this *RPCClient) pickConn() *grpc.ClientConn { + if len(this.conns) == 0 { + return nil + } + return this.conns[rands.Int(0, len(this.conns)-1)] +} diff --git a/internal/web/actions/default/servers/components/componentutils/component_helper.go b/internal/web/actions/default/servers/components/componentutils/component_helper.go index 9e5b3929..2fe7a902 100644 --- a/internal/web/actions/default/servers/components/componentutils/component_helper.go +++ b/internal/web/actions/default/servers/components/componentutils/component_helper.go @@ -18,7 +18,7 @@ func (this *ComponentHelper) BeforeAction(action *actions.ActionObject) { if action.Request.Method != http.MethodGet { return } - action.Data["teaMenu"] = "server" + action.Data["teaMenu"] = "servers" action.Data["mainTab"] = "component" // 顶部标签栏 diff --git a/internal/web/actions/default/servers/components/ssl/certPopup.go b/internal/web/actions/default/servers/components/ssl/certPopup.go new file mode 100644 index 00000000..88f6fef0 --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/certPopup.go @@ -0,0 +1,77 @@ +package ssl + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "github.com/iwind/TeaGo/maps" + timeutil "github.com/iwind/TeaGo/utils/time" + "time" +) + +type CertPopupAction struct { + actionutils.ParentAction +} + +func (this *CertPopupAction) Init() { +} + +func (this *CertPopupAction) RunGet(params struct { + CertId int64 +}) { + certResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + + certConfig := &sslconfigs.SSLCertConfig{} + err = json.Unmarshal(certResp.CertJSON, certConfig) + if err != nil { + this.ErrorPage(err) + return + } + + reverseCommonNames := []string{} + for i := len(certConfig.CommonNames) - 1; i >= 0; i-- { + reverseCommonNames = append(reverseCommonNames, certConfig.CommonNames[i]) + } + + this.Data["info"] = maps.Map{ + "id": certConfig.Id, + "name": certConfig.Name, + "description": certConfig.Description, + "isOn": certConfig.IsOn, + "isAvailable": certConfig.TimeEndAt >= time.Now().Unix(), + "commonNames": reverseCommonNames, + "dnsNames": certConfig.DNSNames, + + // TODO 检查是否为7天或30天内过期 + "beginTime": timeutil.FormatTime("Y-m-d H:i:s", certConfig.TimeBeginAt), + "endTime": timeutil.FormatTime("Y-m-d H:i:s", certConfig.TimeEndAt), + + "isCA": certConfig.IsCA, + "certString": string(certConfig.CertData), + "keyString": string(certConfig.KeyData), + } + + // 引入的服务 + serversResp, err := this.RPC().ServerRPC().FindAllServersWithSSLCertId(this.AdminContext(), &pb.FindAllServersWithSSLCertIdRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + serverMaps := []maps.Map{} + for _, server := range serversResp.Servers { + serverMaps = append(serverMaps, maps.Map{ + "id": server.Id, + "isOn": server.IsOn, + "name": server.Name, + "type": server.Type, + }) + } + this.Data["servers"] = serverMaps + + this.Show() +} diff --git a/internal/web/actions/default/servers/components/ssl/delete.go b/internal/web/actions/default/servers/components/ssl/delete.go new file mode 100644 index 00000000..e9e1d4ab --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/delete.go @@ -0,0 +1,32 @@ +package ssl + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" +) + +type DeleteAction struct { + actionutils.ParentAction +} + +func (this *DeleteAction) RunPost(params struct { + CertId int64 +}) { + // 是否正在被使用 + countResp, err := this.RPC().ServerRPC().CountServersWithSSLCertId(this.AdminContext(), &pb.CountServersWithSSLCertIdRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + if countResp.Count > 0 { + this.Fail("此证书正在被某些服务引用,请先修改服务后再删除。") + } + + _, err = this.RPC().SSLCertRPC().DeleteSSLCert(this.AdminContext(), &pb.DeleteSSLCertRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/components/ssl/downloadCert.go b/internal/web/actions/default/servers/components/ssl/downloadCert.go new file mode 100644 index 00000000..8f9fd922 --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/downloadCert.go @@ -0,0 +1,37 @@ +package ssl + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "strconv" +) + +type DownloadCertAction struct { + actionutils.ParentAction +} + +func (this *DownloadCertAction) Init() { + this.Nav("", "", "") +} + +func (this *DownloadCertAction) RunGet(params struct { + CertId int64 +}) { + certResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + + certConfig := &sslconfigs.SSLCertConfig{} + err = json.Unmarshal(certResp.CertJSON, certConfig) + if err != nil { + this.ErrorPage(err) + return + } + + this.AddHeader("Content-Disposition", "attachment; filename=\"cert-"+strconv.FormatInt(params.CertId, 10)+".pem\";") + this.Write(certConfig.CertData) +} diff --git a/internal/web/actions/default/servers/components/ssl/downloadKey.go b/internal/web/actions/default/servers/components/ssl/downloadKey.go new file mode 100644 index 00000000..8d2a805c --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/downloadKey.go @@ -0,0 +1,37 @@ +package ssl + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "strconv" +) + +type DownloadKeyAction struct { + actionutils.ParentAction +} + +func (this *DownloadKeyAction) Init() { + this.Nav("", "", "") +} + +func (this *DownloadKeyAction) RunGet(params struct { + CertId int64 +}) { + certResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + + certConfig := &sslconfigs.SSLCertConfig{} + err = json.Unmarshal(certResp.CertJSON, certConfig) + if err != nil { + this.ErrorPage(err) + return + } + + this.AddHeader("Content-Disposition", "attachment; filename=\"key-"+strconv.FormatInt(params.CertId, 10)+".pem\";") + this.Write(certConfig.KeyData) +} diff --git a/internal/web/actions/default/servers/components/ssl/downloadZip.go b/internal/web/actions/default/servers/components/ssl/downloadZip.go new file mode 100644 index 00000000..4e29d2cb --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/downloadZip.go @@ -0,0 +1,80 @@ +package ssl + +import ( + "archive/zip" + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "strconv" +) + +type DownloadZipAction struct { + actionutils.ParentAction +} + +func (this *DownloadZipAction) Init() { + this.Nav("", "", "") +} + +func (this *DownloadZipAction) RunGet(params struct { + CertId int64 +}) { + certResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + + certConfig := &sslconfigs.SSLCertConfig{} + err = json.Unmarshal(certResp.CertJSON, certConfig) + if err != nil { + this.ErrorPage(err) + return + } + + z := zip.NewWriter(this.ResponseWriter) + defer func() { + _ = z.Close() + }() + + this.AddHeader("Content-Disposition", "attachment; filename=\"cert-"+strconv.FormatInt(params.CertId, 10)+".zip\";") + + // cert + { + w, err := z.Create("cert.pem") + if err != nil { + this.ErrorPage(err) + return + } + _, err = w.Write(certConfig.CertData) + if err != nil { + this.ErrorPage(err) + return + } + err = z.Flush() + if err != nil { + this.ErrorPage(err) + return + } + } + + // key + if !certConfig.IsCA { + w, err := z.Create("key.pem") + if err != nil { + this.ErrorPage(err) + return + } + _, err = w.Write(certConfig.KeyData) + if err != nil { + this.ErrorPage(err) + return + } + err = z.Flush() + if err != nil { + this.ErrorPage(err) + return + } + } +} diff --git a/internal/web/actions/default/servers/components/ssl/index.go b/internal/web/actions/default/servers/components/ssl/index.go index 32e15927..c6b69bbc 100644 --- a/internal/web/actions/default/servers/components/ssl/index.go +++ b/internal/web/actions/default/servers/components/ssl/index.go @@ -1,7 +1,13 @@ package ssl import ( + "encoding/json" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "github.com/iwind/TeaGo/maps" + timeutil "github.com/iwind/TeaGo/utils/time" + "time" ) type IndexAction struct { @@ -12,7 +18,146 @@ func (this *IndexAction) Init() { this.FirstMenu("index") } -func (this *IndexAction) RunGet(params struct{}) { +func (this *IndexAction) RunGet(params struct { + Type string +}) { + this.Data["type"] = params.Type + + countAll := int64(0) + countCA := int64(0) + countAvailable := int64(0) + countExpired := int64(0) + count7Days := int64(0) + count30Days := int64(0) + + // 计算数量 + { + // all + resp, err := this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{}) + if err != nil { + this.ErrorPage(err) + return + } + countAll = resp.Count + + // CA + resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{ + IsCA: true, + }) + if err != nil { + this.ErrorPage(err) + return + } + countCA = resp.Count + + // available + resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{ + IsAvailable: true, + }) + if err != nil { + this.ErrorPage(err) + return + } + countAvailable = resp.Count + + // expired + resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{ + IsExpired: true, + }) + if err != nil { + this.ErrorPage(err) + return + } + countExpired = resp.Count + + // expire in 7 days + resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{ + ExpiringDays: 7, + }) + if err != nil { + this.ErrorPage(err) + return + } + count7Days = resp.Count + + // expire in 30 days + resp, err = this.RPC().SSLCertRPC().CountSSLCerts(this.AdminContext(), &pb.CountSSLCertRequest{ + ExpiringDays: 30, + }) + if err != nil { + this.ErrorPage(err) + return + } + count30Days = resp.Count + } + + this.Data["countAll"] = countAll + this.Data["countCA"] = countCA + this.Data["countAvailable"] = countAvailable + this.Data["countExpired"] = countExpired + this.Data["count7Days"] = count7Days + this.Data["count30Days"] = count30Days + + // 分页 + var page *actionutils.Page + var listResp *pb.ListSSLCertsResponse + var err error + switch params.Type { + case "": + page = this.NewPage(countAll) + listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{Offset: page.Offset, Size: page.Size}) + case "ca": + page = this.NewPage(countCA) + listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{IsCA: true, Offset: page.Offset, Size: page.Size}) + case "available": + page = this.NewPage(countAvailable) + listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{IsAvailable: true, Offset: page.Offset, Size: page.Size}) + case "expired": + page = this.NewPage(countExpired) + listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{IsExpired: true, Offset: page.Offset, Size: page.Size}) + case "7days": + page = this.NewPage(count7Days) + listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{ExpiringDays: 7, Offset: page.Offset, Size: page.Size}) + case "30days": + page = this.NewPage(count30Days) + listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{ExpiringDays: 30, Offset: page.Offset, Size: page.Size}) + default: + page = this.NewPage(countAll) + listResp, err = this.RPC().SSLCertRPC().ListSSLCerts(this.AdminContext(), &pb.ListSSLCertsRequest{}) + } + if err != nil { + this.ErrorPage(err) + return + } + + certConfigs := []*sslconfigs.SSLCertConfig{} + err = json.Unmarshal(listResp.CertsJSON, &certConfigs) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["certs"] = certConfigs + + certMaps := []maps.Map{} + nowTime := time.Now().Unix() + for _, certConfig := range certConfigs { + countServersResp, err := this.RPC().ServerRPC().CountServersWithSSLCertId(this.AdminContext(), &pb.CountServersWithSSLCertIdRequest{CertId: certConfig.Id}) + if err != nil { + this.ErrorPage(err) + return + } + + certMaps = append(certMaps, maps.Map{ + "beginDay": timeutil.FormatTime("Y-m-d", certConfig.TimeBeginAt), + "endDay": timeutil.FormatTime("Y-m-d", certConfig.TimeEndAt), + "isExpired": nowTime > certConfig.TimeEndAt, + "isAvailable": nowTime <= certConfig.TimeEndAt, + "countServers": countServersResp.Count, + }) + } + this.Data["certInfos"] = certMaps + + this.Data["page"] = page.AsHTML() this.Show() } diff --git a/internal/web/actions/default/servers/components/ssl/init.go b/internal/web/actions/default/servers/components/ssl/init.go index 300f5638..b89b9695 100644 --- a/internal/web/actions/default/servers/components/ssl/init.go +++ b/internal/web/actions/default/servers/components/ssl/init.go @@ -14,6 +14,15 @@ func init() { Helper(componentutils.NewComponentHelper()). Prefix("/servers/components/ssl"). Get("", new(IndexAction)). + GetPost("/uploadPopup", new(UploadPopupAction)). + Post("/delete", new(DeleteAction)). + GetPost("/updatePopup", new(UpdatePopupAction)). + Get("/certPopup", new(CertPopupAction)). + Get("/viewKey", new(ViewKeyAction)). + Get("/viewCert", new(ViewCertAction)). + Get("/downloadKey", new(DownloadKeyAction)). + Get("/downloadCert", new(DownloadCertAction)). + Get("/downloadZip", new(DownloadZipAction)). EndAll() }) } diff --git a/internal/web/actions/default/servers/components/ssl/updatePopup.go b/internal/web/actions/default/servers/components/ssl/updatePopup.go new file mode 100644 index 00000000..39a4246e --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/updatePopup.go @@ -0,0 +1,15 @@ +package ssl + +import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + +type UpdatePopupAction struct { + actionutils.ParentAction +} + +func (this *UpdatePopupAction) Init() { + this.Nav("", "", "") +} + +func (this *UpdatePopupAction) RunGet(params struct{}) { + this.Show() +} diff --git a/internal/web/actions/default/servers/components/ssl/uploadPopup.go b/internal/web/actions/default/servers/components/ssl/uploadPopup.go new file mode 100644 index 00000000..72635f19 --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/uploadPopup.go @@ -0,0 +1,95 @@ +package ssl + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "github.com/iwind/TeaGo/actions" +) + +type UploadPopupAction struct { + actionutils.ParentAction +} + +func (this *UploadPopupAction) Init() { + this.Nav("", "", "") +} + +func (this *UploadPopupAction) RunGet(params struct{}) { + this.Show() +} + +func (this *UploadPopupAction) RunPost(params struct { + Name string + IsCA bool + Description string + IsOn bool + + CertFile *actions.File + KeyFile *actions.File + + Must *actions.Must +}) { + params.Must. + Field("name", params.Name). + Require("请输入证书说明") + + certData := []byte{} + keyData := []byte{} + + if params.CertFile == nil { + this.Fail("请选择要上传的证书文件") + } + var err error + certData, err = params.CertFile.Read() + if err != nil { + this.Fail("读取证书文件内容错误,请重新上传") + } + + if !params.IsCA { + if params.KeyFile == nil { + this.Fail("请选择要上传的私钥文件") + } else { + keyData, err = params.KeyFile.Read() + if err != nil { + this.Fail("读取密钥文件内容错误,请重新上传") + } + } + } + + // 校验 + sslConfig := &sslconfigs.SSLCertConfig{ + IsCA: params.IsCA, + CertData: certData, + KeyData: keyData, + } + err = sslConfig.Init() + if err != nil { + if params.IsCA { + this.Fail("证书校验错误:" + err.Error()) + } else { + this.Fail("证书或密钥校验错误:" + err.Error()) + } + } + + // 保存 + _, err = this.RPC().SSLCertRPC().CreateSSLCert(this.AdminContext(), &pb.CreateSSLCertRequest{ + IsOn: params.IsOn, + Name: params.Name, + Description: params.Description, + ServerName: "", + IsCA: params.IsCA, + CertData: certData, + KeyData: keyData, + TimeBeginAt: sslConfig.TimeBeginAt, + TimeEndAt: sslConfig.TimeEndAt, + DnsNames: sslConfig.DNSNames, + CommonNames: sslConfig.CommonNames, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/components/ssl/viewCert.go b/internal/web/actions/default/servers/components/ssl/viewCert.go new file mode 100644 index 00000000..59484639 --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/viewCert.go @@ -0,0 +1,34 @@ +package ssl + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" +) + +type ViewCertAction struct { + actionutils.ParentAction +} + +func (this *ViewCertAction) Init() { + this.Nav("", "", "") +} + +func (this *ViewCertAction) RunGet(params struct { + CertId int64 +}) { + certResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + + certConfig := &sslconfigs.SSLCertConfig{} + err = json.Unmarshal(certResp.CertJSON, certConfig) + if err != nil { + this.ErrorPage(err) + return + } + this.Write(certConfig.CertData) +} diff --git a/internal/web/actions/default/servers/components/ssl/viewKey.go b/internal/web/actions/default/servers/components/ssl/viewKey.go new file mode 100644 index 00000000..facee9a9 --- /dev/null +++ b/internal/web/actions/default/servers/components/ssl/viewKey.go @@ -0,0 +1,34 @@ +package ssl + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" +) + +type ViewKeyAction struct { + actionutils.ParentAction +} + +func (this *ViewKeyAction) Init() { + this.Nav("", "", "") +} + +func (this *ViewKeyAction) RunGet(params struct { + CertId int64 +}) { + certResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: params.CertId}) + if err != nil { + this.ErrorPage(err) + return + } + + certConfig := &sslconfigs.SSLCertConfig{} + err = json.Unmarshal(certResp.CertJSON, certConfig) + if err != nil { + this.ErrorPage(err) + return + } + this.Write(certConfig.KeyData) +} diff --git a/web/public/js/components/common/labels.js b/web/public/js/components/common/labels.js index a6a23848..521231cc 100644 --- a/web/public/js/components/common/labels.js +++ b/web/public/js/components/common/labels.js @@ -1,4 +1,4 @@ Vue.component("label-on", { props: ["v-is-on"], - template: '
已启用已关闭
' + template: '
已启用已关闭
' }) \ No newline at end of file diff --git a/web/public/js/components/server/http-gzip-box.js b/web/public/js/components/server/http-gzip-box.js index 2bfd6891..cadef2c8 100644 --- a/web/public/js/components/server/http-gzip-box.js +++ b/web/public/js/components/server/http-gzip-box.js @@ -52,7 +52,7 @@ Vue.component("http-gzip-box", { - + Gzip内容最小长度 diff --git a/web/views/@default/@layout.css b/web/views/@default/@layout.css index e309368c..9634b04f 100644 --- a/web/views/@default/@layout.css +++ b/web/views/@default/@layout.css @@ -621,11 +621,6 @@ var.olive { var.dash { border-bottom: 1px dashed grey; } -/** Message **/ -.message .gopher { - width: 30px; - margin-right: 10px; -} /** checkbox **/ .checkbox label a, .checkbox label { diff --git a/web/views/@default/@layout.css.map b/web/views/@default/@layout.css.map index 51cdc8c5..5ef1cd5e 100644 --- a/web/views/@default/@layout.css.map +++ b/web/views/@default/@layout.css.map @@ -1 +1 @@ -{"version":3,"sources":["@left_menu.less","@layout.less"],"names":[],"mappings":"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","file":"@layout.css"} \ No newline at end of file +{"version":3,"sources":["@left_menu.less","@layout.less"],"names":[],"mappings":"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","file":"@layout.css"} \ No newline at end of file diff --git a/web/views/@default/@layout.less b/web/views/@default/@layout.less index bcee24fa..9a10554a 100644 --- a/web/views/@default/@layout.less +++ b/web/views/@default/@layout.less @@ -667,12 +667,6 @@ var.dash { border-bottom: 1px dashed grey; } -/** Message **/ -.message .gopher { - width: 30px; - margin-right: 10px; -} - /** checkbox **/ .checkbox label a, .checkbox label { font-size: 0.8em !important; diff --git a/web/views/@default/@layout_override.css b/web/views/@default/@layout_override.css index 2b6e9397..a6edaef5 100644 --- a/web/views/@default/@layout_override.css +++ b/web/views/@default/@layout_override.css @@ -6,4 +6,7 @@ .ui.toggle.checkbox input:checked ~ label:before { background-color: #21ba45 !important; } +.ui.label.basic { + background-color: white !important; +} /*# sourceMappingURL=@layout_override.css.map */ \ No newline at end of file diff --git a/web/views/@default/@layout_override.css.map b/web/views/@default/@layout_override.css.map index f9af6cb0..ef0f593e 100644 --- a/web/views/@default/@layout_override.css.map +++ b/web/views/@default/@layout_override.css.map @@ -1 +1 @@ -{"version":3,"sources":["@layout_override.less"],"names":[],"mappings":"AACA,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,QAAO;EACrG,oCAAA;;AAGD,GAAG,OAAO,SAAU,MAAK,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,QAAS,QAAO;EACzF,oCAAA","file":"@layout_override.css"} \ No newline at end of file +{"version":3,"sources":["@layout_override.less"],"names":[],"mappings":"AACA,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,QAAO;EACrG,oCAAA;;AAGD,GAAG,OAAO,SAAU,MAAK,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,QAAS,QAAO;EACzF,oCAAA;;AAGD,GAAG,MAAM;EACR,kCAAA","file":"@layout_override.css"} \ No newline at end of file diff --git a/web/views/@default/@layout_override.less b/web/views/@default/@layout_override.less index ee974e1e..aaf8dfaf 100644 --- a/web/views/@default/@layout_override.less +++ b/web/views/@default/@layout_override.less @@ -5,4 +5,8 @@ .ui.toggle.checkbox input:checked ~ .box:before, .ui.toggle.checkbox input:checked ~ label:before { background-color: #21ba45 !important; +} + +.ui.label.basic { + background-color: white !important; } \ No newline at end of file diff --git a/web/views/@default/@layout_popup.css b/web/views/@default/@layout_popup.css index 4f43edfb..6904e646 100644 --- a/web/views/@default/@layout_popup.css +++ b/web/views/@default/@layout_popup.css @@ -211,9 +211,6 @@ td .label.tiny { padding: 2px; font-size: 0.9em; } -td .label.small { - margin-bottom: 0.6em; -} /** Menu **/ .first-menu .menu.text { margin-top: 0 !important; diff --git a/web/views/@default/@layout_popup.css.map b/web/views/@default/@layout_popup.css.map index dae9d6e4..e5da5bf4 100644 --- a/web/views/@default/@layout_popup.css.map +++ b/web/views/@default/@layout_popup.css.map @@ -1 +1 @@ -{"version":3,"sources":["@layout_popup.less"],"names":[],"mappings":"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","file":"@layout_popup.css"} \ No newline at end of file +{"version":3,"sources":["@layout_popup.less"],"names":[],"mappings":";AACA;EACC,WAAA;;AAGD;EACC,aAAA;;AAGD;EACC,qBAAA;;AAGD,CAAC;AAAW,CAAC,SAAS;AAAQ,CAAC,SAAS;AAAS,IAAI;EACpD,sBAAA;;AAGD,CAAC;AAAU,IAAI;AAAU,IAAI;EAC5B,cAAA;;AAGD,IAAI;AAAO,KAAK;AAAO,CAAC;EACvB,sBAAA;;AAGD,CAAC;EACA,iBAAA;;AAGD,IAAI;AAAM,GAAG;EACZ,cAAA;;AAGD,GAAG,IAAI;EACN,mBAAmB,8CAAnB;;AAGD;EACC,uBAAA;;AAGD,MAAM;EACL,sBAAA;;AAGD,MAAM;EACL,sBAAA;;AAGD,MAAM;EACL,sBAAA;;AAGD,MAAO;AAAI,MAAO;EACjB,2BAAA;;AAGD,CAAC;AAAU,GAAG;EACb,yBAAA;EACA,kBAAA;;AAGD,CAAC,QAAS;AAAI,GAAG,QAAS;EACzB,6BAAA;;AAGD;EACC,mBAAA;EACA,2BAAA;EACA,gBAAA;EACA,uBAAA;;AAGD,GAAG;AAAS,CAAC;EACZ,eAAA;;;AAID,GAAG;EACF,UAAA;;AAGD,GAAG;EACF,YAAA;;AAGD,GAAG;EACF,UAAA;;AAGD,GAAG;EACF,WAAA;;;AAID,MAAM;EACL,aAAA;;;AAID;EACC,kBAAA;EACA,UAAA;EACA,UAAA;EACA,mBAAA;EACA,kBAAA;EACA,UAAA;;AASD,mBANqC;EACpC;IACC,SAAA;;;AAIF,KAAK;EACJ,SAAA;;AAGD,KAAK;EACJ,UAAA;;AASD,mBANqC;EACpC,KAAK;IACJ,SAAA;;;AAIF,KAAM,MAAM,GAAE;EACb,WAAA;;AAGD,KAAM,MAAM,GAAE;EACb,WAAA;;AAGD,KAAM,MAAM;EACX,mBAAA;;AAGD,KAAM,MAAM,GAAE;EACb,yCAAA;;AAGD,KAAM,MAAM,GAAE;EACb,mBAAA;;AAGD,KAAM,MAAM,GAAE;EACb,sBAAA;;AAGD,KAAM,MAAM,GAAE,aAAc;EAC3B,mBAAA;;AAGD,KAAM,MAAM,GAAG;EACd,mBAAA;EACA,kBAAA;EACA,gBAAA;;AAGD,KAAM;EACL,mBAAA;EACA,4BAAA;;AAGD,KAAM,GAAG;EACR,gBAAA;;AAGD,KAAM,GAAG,KAAI;EACZ,cAAA;;AAGD,KAAM,GAAG;EACR,gBAAA;EACA,0BAAA;EACA,UAAA;;AAGD,KAAM,GAAG,EAAC;EACT,SAAS,GAAT;;AAGD,KAAM,GAAG,EAAC;EACT,SAAS,GAAT;;AAGD,KAAM;EACL,mBAAA;;AAGD,KAAM,GAAG,KAAI;EACZ,gBAAA;;AAGD,KAAM,QAAO;EACZ,gBAAA;EACA,cAAA;EACA,gBAAA;;;AAID,KAAK;EACJ,gBAAA;;AAGD,KAAK,KAAK;EACT,UAAA;EACA,WAAA;;;AAID;EACC,wBAAA;;;AAID,iBAAkB;EACjB,2BAAA;;AAGD,iBAAkB,MAAK;EACtB,UAAA;;AAGD,iBAAkB,MAAM;EACvB,2BAAA;;AAGD,MAAM;EACL,sBAAA;;;AAWD,mBAPqC;EACpC,OAAO,IAAI;IACV,sBAAA;;;;AAKF,KAAK;EACJ,0BAAA;;AAGD,KAAK;EACJ,yBAAA;;AAGD,EAAG,OAAM;EACR,YAAA;EACA,gBAAA;;;AAID,WAAY,MAAK;EAChB,wBAAA;EACA,2BAAA;;AAGD,WAAY;EACX,wBAAA;EACA,2BAAA;;AAGD,YAAa,MAAK;EACjB,wBAAA;EACA,2BAAA;;AAGD,YAAa,MAAK,KAAM;EACvB,kBAAA;;AAGD,YAAa;EACZ,wBAAA;;AAGD,KAAM;EACL,aAAA;;;AAID,IAAI;AAAQ,GAAG;EACd,yBAAA;;AAGD,GAAG;EACF,8BAAA;;;AAID,QAAS;EACR,WAAA;EACA,kBAAA;;;AAID,SAAU,MAAM;AAAG,SAAU;EAC5B,2BAAA;;;AAID;EACC,eAAA;EAEA,2BAAA;;AAHD,KAKC;EACC,qBAAA;EACA,mBAAA;EACA,WAAA;EACA,iBAAA;EACA,SAAA;EACA,gBAAA;EACA,sBAAA;EACA,cAAA;;AAbF,KAgBC,EAAC;EACA,8BAAA;EACA,YAAA;;AAlBF,KAqBC,EAAC;EACA,gBAAA;;;AAKF;EACC,kBAAA;;AAGD,cAAc;AAAQ,aAAa;AAAQ,YAAY;EACtD,iCAAA;;AAGD;AAAgB;AAAe;EAC9B,iCAAA;;AAGD;EACC,2BAAA","file":"@layout_popup.css"} \ No newline at end of file diff --git a/web/views/@default/@layout_popup.html b/web/views/@default/@layout_popup.html index d31c56c6..75b78990 100644 --- a/web/views/@default/@layout_popup.html +++ b/web/views/@default/@layout_popup.html @@ -9,6 +9,7 @@ {$TEA.VUE} + {$echo "header"} diff --git a/web/views/@default/@layout_popup.less b/web/views/@default/@layout_popup.less index 7be3f842..7c9d6c60 100644 --- a/web/views/@default/@layout_popup.less +++ b/web/views/@default/@layout_popup.less @@ -255,10 +255,6 @@ td .label.tiny { font-size: 0.9em; } -td .label.small { - margin-bottom: 0.6em; -} - /** Menu **/ .first-menu .menu.text { margin-top: 0 !important; diff --git a/web/views/@default/servers/components/ssl/certPopup.css b/web/views/@default/servers/components/ssl/certPopup.css new file mode 100644 index 00000000..78632969 --- /dev/null +++ b/web/views/@default/servers/components/ssl/certPopup.css @@ -0,0 +1,15 @@ +.pre-box { + padding: 1em; + margin: 0; + line-height: 1.7; + -ms-word-break: break-all; + word-break: break-all; + font-size: 0.9em; + background: rgba(0, 0, 0, 0.05); + overflow-y: auto; + max-height: 20em; +} +.pre-box::-webkit-scrollbar { + width: 6px; +} +/*# sourceMappingURL=certPopup.css.map */ \ No newline at end of file diff --git a/web/views/@default/servers/components/ssl/certPopup.css.map b/web/views/@default/servers/components/ssl/certPopup.css.map new file mode 100644 index 00000000..0aa09144 --- /dev/null +++ b/web/views/@default/servers/components/ssl/certPopup.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["certPopup.less"],"names":[],"mappings":"AAAA;EACC,YAAA;EACA,SAAA;EACA,gBAAA;EACA,yBAAA;EACA,qBAAA;EACA,gBAAA;EACA,+BAAA;EACA,gBAAA;EACA,gBAAA;;AAGD,QAAQ;EACP,UAAA","file":"certPopup.css"} \ No newline at end of file diff --git a/web/views/@default/servers/components/ssl/certPopup.html b/web/views/@default/servers/components/ssl/certPopup.html new file mode 100644 index 00000000..4e9ee5bf --- /dev/null +++ b/web/views/@default/servers/components/ssl/certPopup.html @@ -0,0 +1,74 @@ +{$layout "layout_popup"} + +

证书详情

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
证书说明{{info.name}}
详细说明{{info.decription}}
证书状态 + 有效中 + 已过期 +
发行信息 +
+
+ {{commonName}} +
+
+
域名 + {{dnsName}} +
有效期{{info.beginTime}} - {{info.endTime}}
引用服务 + 暂时没有引用此证书的服务。 +
+ {{server.name}} +
+
证书文件下载 + [ZIP下载]   + [证书下载]   + [私钥下载] +
证书预览 +
{{info.certString}}
+
+ [浏览器新窗口打开] +
+
私钥预览
{{info.keyString}}
+
+ [浏览器新窗口打开] +
+
\ No newline at end of file diff --git a/web/views/@default/servers/components/ssl/certPopup.js b/web/views/@default/servers/components/ssl/certPopup.js new file mode 100644 index 00000000..8a026c6c --- /dev/null +++ b/web/views/@default/servers/components/ssl/certPopup.js @@ -0,0 +1,10 @@ +Tea.context(function () { + // 打印缩进 + this.indent = function (index) { + let indent = "" + for (let i = 0; i < index; i++) { + indent += "     " + } + return indent + } +}) \ No newline at end of file diff --git a/web/views/@default/servers/components/ssl/certPopup.less b/web/views/@default/servers/components/ssl/certPopup.less new file mode 100644 index 00000000..48715270 --- /dev/null +++ b/web/views/@default/servers/components/ssl/certPopup.less @@ -0,0 +1,15 @@ +.pre-box { + padding: 1em; + margin: 0; + line-height: 1.7; + -ms-word-break: break-all; + word-break: break-all; + font-size: 0.9em; + background: rgba(0, 0, 0, 0.05); + overflow-y: auto; + max-height: 20em; +} + +.pre-box::-webkit-scrollbar { + width: 6px; +} diff --git a/web/views/@default/servers/components/ssl/index.html b/web/views/@default/servers/components/ssl/index.html index fb2dbfb9..73820460 100644 --- a/web/views/@default/servers/components/ssl/index.html +++ b/web/views/@default/servers/components/ssl/index.html @@ -2,5 +2,55 @@ {$template "/left_menu"}
-

此功能暂未开放敬请期待。

+ + 所有证书({{countAll}}) + CA证书({{countCA}}) + 有效证书({{countAvailable}}) + 过期证书({{countExpired}}) + 7天内过期({{count7Days}}) + 30天过期({{count30Days}}) + | + [上传证书] + + +

暂时还没有相关的证书。

+ + + + + + + + + + + + + + + + + + + + + + + +
证书说明顶级发行组织域名生效日期过期日期引用服务状态操作
{{cert.name}} + {{cert.commonNames[cert.commonNames.length-1]}} + +
+ {{dnsName}} +
+
{{certInfos[index].beginDay}}{{certInfos[index].endDay}}{{certInfos[index].countServers}} + 已过期 + 有效中 + + 详情   + 修改   + 删除 +
+ +
\ No newline at end of file diff --git a/web/views/@default/servers/components/ssl/index.js b/web/views/@default/servers/components/ssl/index.js new file mode 100644 index 00000000..2852f907 --- /dev/null +++ b/web/views/@default/servers/components/ssl/index.js @@ -0,0 +1,33 @@ +Tea.context(function () { + // 上传证书 + this.uploadCert = function () { + teaweb.popup("/servers/components/ssl/uploadPopup", { + height: "28em", + callback: function () { + teaweb.success("上传成功", function () { + window.location.reload() + }) + } + }) + } + + // 删除证书 + this.deleteCert = function (certId) { + let that = this + teaweb.confirm("确定要删除此证书吗?", function () { + that.$post("/servers/components/ssl/delete") + .params({ + certId: certId + }) + .refresh() + }) + } + + // 查看证书 + this.viewCert = function (certId) { + teaweb.popup("/servers/components/ssl/certPopup?certId=" + certId, { + height: "28em", + width: "48em" + }) + } +}) \ No newline at end of file diff --git a/web/views/@default/servers/components/ssl/uploadPopup.html b/web/views/@default/servers/components/ssl/uploadPopup.html new file mode 100644 index 00000000..e200ac8d --- /dev/null +++ b/web/views/@default/servers/components/ssl/uploadPopup.html @@ -0,0 +1,59 @@ +{$layout "layout_popup"} + +

上传证书

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
证书说明 * + +

可以简单说明证书的用途。

+
证书类型 + +
选择证书文件 * + +

内容中通常含有"-----BEGIN CERTIFICATE-----"类似的信息。

+
选择私钥文件 * + +

内容中通常含有"-----BEGIN RSA PRIVATE KEY-----"类似的信息。

+
详细说明 + +
是否启用 +
+ + +
+
+ +
\ No newline at end of file diff --git a/web/views/@default/servers/components/ssl/uploadPopup.js b/web/views/@default/servers/components/ssl/uploadPopup.js new file mode 100644 index 00000000..fbdcfddd --- /dev/null +++ b/web/views/@default/servers/components/ssl/uploadPopup.js @@ -0,0 +1,4 @@ +Tea.context(function () { + this.success = NotifyPopup + this.isCA = 0 +}) \ No newline at end of file diff --git a/web/views/@default/servers/server/settings/https/index.html b/web/views/@default/servers/server/settings/https/index.html index 3815fb14..0792a2fc 100644 --- a/web/views/@default/servers/server/settings/https/index.html +++ b/web/views/@default/servers/server/settings/https/index.html @@ -3,6 +3,7 @@ {$template "/left_menu"}
+

提醒:HTTP2、证书等信息修改后,可能需要清空浏览器缓存后才能浏览效果。