|
|
using System;
|
|
|
using System.Collections;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Collections.Specialized;
|
|
|
using System.Linq;
|
|
|
using System.Security.Cryptography.X509Certificates;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using UMC.Data;
|
|
|
using UMC.Data.Entities;
|
|
|
using UMC.Host;
|
|
|
using UMC.Net;
|
|
|
using UMC.ITME.Entities;
|
|
|
using UMC.Security;
|
|
|
using UMC.Web;
|
|
|
using UMC.Web.UI;
|
|
|
|
|
|
|
|
|
namespace UMC.ITME.Activities
|
|
|
{
|
|
|
[Apiumc("ITME", "Server", Auth = WebAuthType.Admin, Desc = "Http服务配置")]
|
|
|
public class SiteServerActivity : WebActivity
|
|
|
{
|
|
|
|
|
|
public override void ProcessActivity(WebRequest request, WebResponse response)
|
|
|
{
|
|
|
|
|
|
var hosts = UMC.Data.Reflection.Configuration("host");
|
|
|
var model = this.AsyncDialog("Model", akey =>
|
|
|
{
|
|
|
|
|
|
var ui = UISection.Create(new UITitle("网关服务"));
|
|
|
|
|
|
var unix = hosts.Providers.Where(r => r.Type == "unix");
|
|
|
|
|
|
var provider = Data.WebResource.Instance().Provider;
|
|
|
ui.AddCell("主协议", provider["scheme"] ?? "http", new UIClick(request.Model, request.Command, "Domain"))
|
|
|
.AddCell("主域名", provider["domain"] ?? "未设置", new UIClick(request.Model, request.Command, "Domain"));
|
|
|
|
|
|
ui.NewSection().AddCell("日志服务", new UIClick(request, "Log"));
|
|
|
|
|
|
var http = hosts.Providers.Where(r => r.Type == "http");
|
|
|
|
|
|
var httpUI = ui.NewSection();
|
|
|
httpUI.AddCell("http", new UIClick(request, "Http"));
|
|
|
if (http.Count() > 0)
|
|
|
{
|
|
|
foreach (var p in http)
|
|
|
{
|
|
|
var cell = UI.UI("端口", p.Attributes["port"] ?? "80");
|
|
|
httpUI.Delete(cell, new UIEventText().Click(new UIClick(request, p.Name)));
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
UIDesc desc = new UIDesc("未配置Http端口");
|
|
|
desc.Desc("{icon}\n{desc}").Put("icon", "\uf24a");
|
|
|
desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
|
|
|
httpUI.Add(desc);
|
|
|
|
|
|
}
|
|
|
|
|
|
var https = hosts.Providers.Where(r => r.Type == "https");
|
|
|
var httpsUI = ui.NewSection();
|
|
|
httpsUI.AddCell("https", new UIClick(request, "Https"));
|
|
|
if (https.Count() > 0)
|
|
|
{
|
|
|
foreach (var p in https)
|
|
|
{
|
|
|
var cell = UI.UI("端口", p.Attributes["port"] ?? "80");//, new UIClick(p.Name).Send(request.Model, request.Command));
|
|
|
httpsUI.Delete(cell, new UIEventText().Click(new UIClick(request, akey, p.Name, "Type", "Del")));
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
UIDesc desc = new UIDesc("未配置Https端口");
|
|
|
desc.Desc("{icon}\n{desc}").Put("icon", "\uf24a");
|
|
|
desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
|
|
|
httpsUI.Add(desc);
|
|
|
}
|
|
|
var tcp = hosts.Providers.Where(r => r.Type == "tcp");
|
|
|
var tcpUI = ui.NewSection();
|
|
|
tcpUI.AddCell("tcp", "", new UIClick(request, "Tcp"));
|
|
|
if (tcp.Count() > 0)
|
|
|
{
|
|
|
foreach (var p in tcp)
|
|
|
{
|
|
|
var cell = UI.UI(p.Attributes["port"] ?? "80", p.Attributes["server"]);//, new UIClick(p.Name).Send(request.Model, request.Command));
|
|
|
tcpUI.Delete(cell, new UIEventText().Click(new UIClick(request, akey, p.Name, "Type", "Del")));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var udp = hosts.Providers.Where(r => r.Type == "udp");
|
|
|
var udpUI = ui.NewSection();
|
|
|
|
|
|
udpUI.AddCell("udp", "", new UIClick(request, "Udp"));
|
|
|
if (udp.Count() > 0)
|
|
|
{
|
|
|
foreach (var p in udp)
|
|
|
{
|
|
|
var cell = UI.UI(p.Attributes["port"], p.Attributes["server"]);//, new UIClick(p.Name).Send(request.Model, request.Command));
|
|
|
udpUI.Delete(cell, new UIEventText().Click(new UIClick(request, akey, p.Name, "Type", "Del")));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
var sslUI = ui.NewSection();
|
|
|
|
|
|
sslUI.AddCell("证书", new UIClick(request, "Cert"));
|
|
|
var now = UMC.Data.Utility.TimeSpan();
|
|
|
|
|
|
var lr = new Dictionary<string, Certificater>(Certificater.Certificates);
|
|
|
|
|
|
var certs = HotCache.Find(new SiteCert { }, false, 0, 500, out var nextIndex);
|
|
|
foreach (var r in certs)
|
|
|
{
|
|
|
var cell = UI.UI(r.Domain, Utility.Expire(now, r.ExpirationTime ?? 0, "正签发"), new UIClick(request, akey, "CSR", "Domain", r.Domain));
|
|
|
sslUI.Delete(cell, new UIEventText().Click(new UIClick(request, akey, "Del", "Domain", r.Domain)));
|
|
|
lr.Remove(r.Domain);
|
|
|
}
|
|
|
var ls = lr.Values.OrderBy(r =>
|
|
|
{
|
|
|
|
|
|
if (r.Certificate != null)
|
|
|
{
|
|
|
r.Time = Utility.TimeSpan(Convert.ToDateTime(r.Certificate.GetExpirationDateString()));
|
|
|
|
|
|
}
|
|
|
return r.Time;
|
|
|
});
|
|
|
|
|
|
foreach (var r in ls)
|
|
|
{
|
|
|
var cell = UI.UI(r.Name, Utility.Expire(now, r.Time, "正签发"), new UIClick(request, akey, "CSR", "Domain", r.Name));
|
|
|
sslUI.Delete(cell, new UIEventText().Click(new UIClick(request, akey, "Del", "Domain", r.Name)));
|
|
|
}
|
|
|
if (certs.Length == 0 && lr.Count == 0)
|
|
|
{
|
|
|
UIDesc desc = new UIDesc("未有SSL/TLS证书");
|
|
|
desc.Desc("{icon}\n{desc}").Put("icon", "\uf24a");
|
|
|
desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
|
|
|
sslUI.Add(desc);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
ui.UIFootBar = new UIFootBar() { IsFixed = true };
|
|
|
ui.UIFootBar.AddText(new UIEventText("申请免费证书").Click(new UIClick(request, "ApplyCert")),
|
|
|
new UIEventText("重新加载").Click(new UIClick("Http", "Bridge", "Reload")).Style(new UIStyle().BgColor()));
|
|
|
|
|
|
ui.SendTo(this.Context, $"{request.Model}.{request.Command}");
|
|
|
|
|
|
return this.DialogValue("none");
|
|
|
});
|
|
|
switch (model)
|
|
|
{
|
|
|
case "Certs":
|
|
|
{
|
|
|
|
|
|
var ui = UISection.Create(new UITitle("域名证书"));
|
|
|
}
|
|
|
break;
|
|
|
case "Log":
|
|
|
{
|
|
|
var setting = this.AsyncDialog("LogSetting", r =>
|
|
|
{
|
|
|
var provider = UMC.Data.Reflection.Configuration("assembly")?["Log"];
|
|
|
|
|
|
var fm = new UIFormDialog() { Title = "日志服务器" };
|
|
|
fm.AddText("服务器", "host", provider?["host"]).NotRequired();
|
|
|
fm.AddNumber("端口", "port", provider?["port"] ?? "514").NotRequired();
|
|
|
fm.AddFooter("采用Syslog格式吐出日志");
|
|
|
fm.Submit("确认", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
var cfg = UMC.Data.Reflection.Configuration("assembly");
|
|
|
var p = Provider.Create("Log", "LogSetting");
|
|
|
if (String.IsNullOrEmpty(setting["host"]) || String.IsNullOrEmpty(setting["port"]))
|
|
|
{
|
|
|
cfg.Remove("Log");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
p.Attributes["host"] = setting["host"];
|
|
|
p.Attributes["port"] = setting["port"];
|
|
|
cfg.Add(p);
|
|
|
}
|
|
|
UMC.Data.Reflection.Configuration("assembly", cfg);
|
|
|
LogSetting.Instance().LoadConf();
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
}
|
|
|
break;
|
|
|
case "Unix":
|
|
|
hosts.Add(UMC.Data.Provider.Create("unix", "unix"));
|
|
|
UMC.Data.Reflection.Configuration("host", hosts);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
break;
|
|
|
case "Domain":
|
|
|
var provider = Data.WebResource.Instance().Provider;
|
|
|
var Domains = this.AsyncDialog("Domain", r =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "网关参数" };
|
|
|
|
|
|
fm.AddText("主域名", "domain", provider["domain"]);
|
|
|
var union = provider["union"] ?? ".";
|
|
|
var scheme = provider["scheme"] ?? "http";
|
|
|
// fm.AddRadio("连接符", "union").Put(".", ".", union == ".").Put("-", "-", union == "-");
|
|
|
fm.AddRadio("主协议", "scheme").Put("http", "http", scheme == "http").Put("https", "https", scheme == "https");
|
|
|
fm.Submit("确认", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
|
|
|
provider.Attributes["scheme"] = Domains["scheme"];
|
|
|
provider.Attributes["domain"] = Domains["domain"];
|
|
|
// provider.Attributes["union"] = Domains["union"];
|
|
|
|
|
|
var pc = UMC.Data.Reflection.Configuration("assembly") ?? new ProviderConfiguration();
|
|
|
|
|
|
pc.Add(provider);
|
|
|
UMC.Data.Reflection.Configuration("assembly", pc);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
break;
|
|
|
case "Share":
|
|
|
{
|
|
|
var secret = UMC.Data.WebResource.Instance().Provider["appSecret"];
|
|
|
if (String.IsNullOrEmpty(secret))
|
|
|
{
|
|
|
this.Prompt("当前版本未登记注册", false);
|
|
|
response.Redirect("System", "License");
|
|
|
}
|
|
|
var webr2 = new Uri(APIProxy.Uri, "Certificater").WebRequest();
|
|
|
UMC.ITME.Utility.Sign(webr2, secret);
|
|
|
|
|
|
var webr = webr2.Post(new WebMeta().Put("type", "share"));
|
|
|
|
|
|
var str = webr.ReadAsString();
|
|
|
|
|
|
var hs = JSON.Deserialize<WebMeta>(str);
|
|
|
this.Context.Send("Clipboard", new WebMeta().Put("text", hs["text"]).Put("msg", hs["msg"]), true);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
case "Url":
|
|
|
response.Redirect(new Uri(this.AsyncDialog("Url", r => this.Prompt("请输入Url"))));
|
|
|
break;
|
|
|
case "Statement":
|
|
|
{
|
|
|
|
|
|
if ((request.SendValues?.ContainsKey("limit") ?? false) == false)
|
|
|
{
|
|
|
this.Context.Send(new UISectionBuilder(request.Model, request.Command, request.Arguments)
|
|
|
|
|
|
.Builder(), true);
|
|
|
}
|
|
|
|
|
|
var webr = new Uri(APIProxy.Uri, "/UMC/System/Docs/apiumc?limit=30").WebRequest();
|
|
|
|
|
|
response.Redirect(JSON.Expression(webr.Get().ReadAsString()));
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
case "VIP":
|
|
|
{
|
|
|
this.AsyncDialog("VIP", g =>
|
|
|
{
|
|
|
var ui = new UISheetDialog() { Title = "服务升级" };
|
|
|
ui.Put(new UIClick(request, "Model", "Recharge", "Code", "CName") { Text = "订购开拓专享" })
|
|
|
.Put(new UIClick(request, "BuyAll") { Text = "订购企业专享" });
|
|
|
return ui;
|
|
|
});
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
case "BuyAll":
|
|
|
response.Redirect(request.Model, request.Command, new WebMeta().Put("Model", "Recharge", "Code", "*"), true);
|
|
|
break;
|
|
|
case "Site":
|
|
|
var Site = this.AsyncDialog("Site", r =>
|
|
|
{
|
|
|
return new UITextDialog(hosts.ProviderType) { Title = "服务站点" };
|
|
|
});
|
|
|
hosts.ProviderType = Site;
|
|
|
UMC.Data.Reflection.Configuration("host", hosts);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
break;
|
|
|
case "Cert":
|
|
|
{
|
|
|
|
|
|
var httpPorts2 = this.AsyncDialog("Cert", r =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "证书" };
|
|
|
fm.AddText("域名", "Domain", String.Empty);
|
|
|
fm.AddTextarea("公钥", "publicKey", String.Empty).Put("Rows", 10).PlaceHolder("以-----BEGIN CERTIFICATE-----开始的证书").Put("tip", "公钥证书");
|
|
|
fm.AddTextarea("私钥", "privateKey", String.Empty).Put("Rows", 10).PlaceHolder("以-----BEGIN RSA PRIVATE KEY-----开始的证书").Put("tip", "私钥证书");
|
|
|
fm.Submit("确认添加", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
|
|
|
// var certs = UMC.Data.Reflection.Configuration("certs");
|
|
|
var Domain = httpPorts2["Domain"];
|
|
|
var publicKey = httpPorts2["publicKey"];
|
|
|
var privateKey = httpPorts2["privateKey"];
|
|
|
X509Certificate2 x509 = null;
|
|
|
try
|
|
|
{
|
|
|
x509 = X509Certificate2.CreateFromPem(publicKey, privateKey);
|
|
|
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
this.Prompt("证书不正确");
|
|
|
}
|
|
|
if (x509.NotAfter < DateTime.Now)
|
|
|
{
|
|
|
x509.Dispose();
|
|
|
this.Prompt("此证书已过期");
|
|
|
}
|
|
|
|
|
|
|
|
|
HotCache.Put(new Entities.SiteCert
|
|
|
{
|
|
|
Domain = Domain,
|
|
|
IsApiumc = true,
|
|
|
ExpirationTime = Utility.TimeSpan(x509.NotAfter),
|
|
|
CheckTime = Utility.TimeSpan(),
|
|
|
PrivateKey = privateKey,
|
|
|
PublicKey = publicKey
|
|
|
});
|
|
|
|
|
|
|
|
|
Certificater.Certificates[Domain] = new Certificater
|
|
|
{
|
|
|
Name = Domain,
|
|
|
Certificate = x509
|
|
|
};
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
break;
|
|
|
}
|
|
|
case "Del":
|
|
|
{
|
|
|
var host = this.AsyncDialog("Domain", "none");
|
|
|
if (Certificater.Certificates.TryGetValue(host, out var _v))
|
|
|
{
|
|
|
if (Certificater.Certificates.Remove(host))
|
|
|
{
|
|
|
var certs = UMC.Data.Reflection.Configuration("certs");
|
|
|
certs.Remove(host);
|
|
|
UMC.Data.Reflection.Configuration("certs", certs);
|
|
|
}
|
|
|
}
|
|
|
HotCache.Delete(new SiteCert { Domain = host });
|
|
|
|
|
|
this.Context.Send($"{request.Model}.{request.Command}.Del", true);
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
case "ApplyCert":
|
|
|
{
|
|
|
var host = UIDialog.AsyncDialog(this.Context, "Domain", g =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "申请证书" };
|
|
|
fm.AddText("域名", "Domain", String.Empty);
|
|
|
fm.AddRadio("", "Dcv").Put("自动智能验证域名所有权", "file", true)
|
|
|
.Put("CName方式验证域名所有权", "cname");
|
|
|
fm.Submit("确认申请", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
var Dcv = this.AsyncDialog("Dcv", "file");
|
|
|
if (System.Text.RegularExpressions.Regex.IsMatch(host, @"^([a-z0-9\*]([a-z0-9\-]{0,61}[a-z0-9])?\.)+[a-z0-9]{1,6}$") == false)
|
|
|
{
|
|
|
this.Prompt("域名格式不正确");
|
|
|
}
|
|
|
|
|
|
var secret = UMC.Data.WebResource.Instance().Provider["appSecret"];
|
|
|
if (String.IsNullOrEmpty(secret))
|
|
|
{
|
|
|
this.Prompt("当前版本未登记注册", false);
|
|
|
response.Redirect("System", "License");
|
|
|
}
|
|
|
var webr2 = new Uri(APIProxy.Uri, "Certificater").WebRequest();
|
|
|
UMC.ITME.Utility.Sign(webr2, secret);
|
|
|
|
|
|
var webr = webr2.Post(new WebMeta().Put("type", "apply", "domain", host).Put("dcv", Dcv));
|
|
|
|
|
|
var str = webr.ReadAsString();
|
|
|
if (webr.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
{
|
|
|
var hs = JSON.Deserialize<WebMeta>(str);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", false);
|
|
|
if (string.Equals(hs["code"], "success"))
|
|
|
{
|
|
|
if (this.Context.Request.UrlReferrer?.LocalPath?.StartsWith("/UMC.SSL") == true)
|
|
|
{
|
|
|
this.Prompt("正在签发证书,请等候片刻");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
response.Redirect(request.Model, request.Command, new UIConfirmDialog("正在签发证书,确认进入证书签发详情", "CSR"), new WebMeta("Domain", host), true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if (string.Equals(hs["code"], "completed"))
|
|
|
{
|
|
|
webr2.Post(new WebMeta().Put("type", "cert", "domain", host), UMC.ITME.Utility.Certificate);
|
|
|
this.Prompt(hs["msg"]);
|
|
|
}
|
|
|
else if (string.Equals(hs["code"], "verifing"))
|
|
|
{
|
|
|
response.Redirect(request.Model, request.Command, new WebMeta("Domain", host).Put("Model", "CSR"), true);
|
|
|
|
|
|
}
|
|
|
else if (string.Equals(hs["code"], "privateKey"))
|
|
|
{
|
|
|
response.Redirect(request.Model, request.Command, new WebMeta("Domain", host).Put("Model", "PrivateKey"), true);
|
|
|
|
|
|
}
|
|
|
else if (string.Equals(hs["code"], "url"))
|
|
|
{
|
|
|
var confi = new UIConfirmDialog(hs["msg"], "Url");
|
|
|
confi.Config.Put("Action", true);
|
|
|
response.Redirect(request.Model, request.Command, confi, new WebMeta("Url", hs["url"]), true);
|
|
|
}
|
|
|
else if (string.Equals(hs["code"], "vip"))
|
|
|
{
|
|
|
response.Redirect(request.Model, request.Command, new UIConfirmDialog(hs["msg"], "VIP"), true);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
this.Prompt("提示", hs["msg"], false);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
this.Prompt("错误", $"请确保域名“{host}”解释到服务器,并开放80端口");
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case "CSR":
|
|
|
{
|
|
|
var host = UIDialog.AsyncDialog(this.Context, "Domain", g =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "申请证书" };
|
|
|
fm.AddText("域名", "Domain", String.Empty);
|
|
|
return fm;
|
|
|
});
|
|
|
var webr2 = new Uri(APIProxy.Uri, "Certificater").WebRequest();
|
|
|
|
|
|
var secret = UMC.Data.WebResource.Instance().Provider["appSecret"];
|
|
|
if (String.IsNullOrEmpty(secret))
|
|
|
{
|
|
|
this.Prompt("当前版本未登记注册", false);
|
|
|
response.Redirect("System", "License");
|
|
|
}
|
|
|
UMC.ITME.Utility.Sign(webr2, secret);
|
|
|
|
|
|
var certmodel = this.AsyncDialog("CertModel", rm =>
|
|
|
{
|
|
|
|
|
|
var json = webr2.Post(new WebMeta().Put("type", "info", "domain", host)).ReadAsString();
|
|
|
|
|
|
|
|
|
var hash = JSON.Deserialize<Hashtable>(json);// ?? new Hashtable();
|
|
|
|
|
|
if (hash == null)
|
|
|
{
|
|
|
this.Prompt(json);
|
|
|
}
|
|
|
var ui = UISection.Create(new UITitle("域名证书"));
|
|
|
if (hash.ContainsKey("isEnterprise"))
|
|
|
{
|
|
|
ui.AddCell("会员类型", hash["vip"] as string, new UIClick(request, "BuyAll"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ui.AddCell("会员类型", hash["vip"] as string, new UIClick(request, "VIP"));
|
|
|
}
|
|
|
ui.AddCell("服务说明", "去了解更多权益", new UIClick(request, "Statement"));//.Header.Put("text", "公共服务");
|
|
|
|
|
|
var lu = ui.NewSection().AddCell("域名", hash["domain"] as string);
|
|
|
|
|
|
var strBtn = "从新签发";
|
|
|
if (hash.ContainsKey("order"))
|
|
|
{
|
|
|
lu.AddCell("单号", hash["order"] as string);
|
|
|
|
|
|
var csr = ui.NewSection();
|
|
|
switch (hash["status"] as string)
|
|
|
{
|
|
|
case "domain_verifing":
|
|
|
csr.AddCell("证书状态", hash["state"] as string, new UIClick(request, rm, "verifing"));
|
|
|
break;
|
|
|
case "check":
|
|
|
csr.AddCell("证书状态", hash["state"] as string, new UIClick(request, rm, "check"));
|
|
|
|
|
|
break;
|
|
|
case "cname":
|
|
|
csr.AddCell("证书状态", hash["state"] as string);
|
|
|
csr.NewSection()//.AddCell("主域名", hash["cname"] as string)
|
|
|
.AddCell("记录类型", "CNAME")
|
|
|
.AddCell("主机记录", "点击复制", new UIClick(new WebMeta().Put("text", hash["auth_path"] as string)) { Key = "Clipboard" })
|
|
|
.AddCell("记录值", "点击复制", new UIClick(new WebMeta().Put("text", hash["auth_val"] as string)) { Key = "Clipboard" })
|
|
|
.Header.Put("text", "请在主域名解释添加如下记录");
|
|
|
break;
|
|
|
default:
|
|
|
|
|
|
csr.AddCell("证书状态", hash["state"] as string);
|
|
|
break;
|
|
|
}
|
|
|
if (hash.ContainsKey("expire"))
|
|
|
{
|
|
|
csr.AddCell("证书过期", hash["expire"] as string);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if (hash.ContainsKey("state"))
|
|
|
{
|
|
|
ui.NewSection().AddCell("证书状态", hash["state"] as string);
|
|
|
}
|
|
|
|
|
|
if (Certificater.Certificates.TryGetValue(host, out var _v))
|
|
|
{
|
|
|
if (_v.Certificate != null)
|
|
|
{
|
|
|
var cn = _v.Certificate.Subject.Split(',').First(r => r.Trim().StartsWith("CN=")).Substring(3);
|
|
|
if (hash.ContainsKey("expire") && hash.ContainsKey("order"))
|
|
|
{
|
|
|
ui.NewSection().AddCell("证书公用名", cn);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ui.NewSection().AddCell("证书公用名", cn).AddCell("证书过期", Utility.Expire(Utility.TimeSpan(), Utility.TimeSpan(Convert.ToDateTime(_v.Certificate.GetExpirationDateString())), "正签发"));
|
|
|
}
|
|
|
}
|
|
|
else if (hash.ContainsKey("order"))
|
|
|
{
|
|
|
strBtn = "下载证书";
|
|
|
}
|
|
|
}
|
|
|
else if (hash.ContainsKey("order"))
|
|
|
{
|
|
|
strBtn = "下载证书";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
strBtn = "免费申请";
|
|
|
|
|
|
|
|
|
UIDesc desc = new UIDesc("未有证书,请申请");
|
|
|
desc.Desc("{icon}\n{desc}").Put("icon", "\uf24a");
|
|
|
desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
|
|
|
ui.NewSection().Add(desc);
|
|
|
|
|
|
|
|
|
}
|
|
|
if (hash.ContainsKey("isLock"))
|
|
|
{
|
|
|
ui.NewSection().AddCell("自动续签", hash["contract"] as string);
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ui.NewSection().AddCell("自动续签", hash["contract"] as string, new UIClick(request, "Model", "Recharge", "Code", hash["domain"] as string));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ui.NewSection().AddCell("联系官方", "让天才工程师为你服务", new UIClick("System", "License", "Contact"));
|
|
|
|
|
|
ui.UIFootBar = new UIFootBar() { IsFixed = true };
|
|
|
switch (hash["status"] as string)
|
|
|
{
|
|
|
case "cname":
|
|
|
ui.UIFootBar.AddText(new UIEventText("验证域名记录").Click(new UIClick(request, rm, "verifing")),
|
|
|
new UIEventText("订阅自动续签").Click(new UIClick(request, "Model", "Recharge", "Code", hash["root"] as string)).Style(new UIStyle().BgColor()));
|
|
|
|
|
|
break;
|
|
|
default:
|
|
|
ui.UIFootBar.AddText(new UIEventText(strBtn).Click(new UIClick(request, "Model", "ApplyCert", "Domain", hash["domain"] as string)),
|
|
|
new UIEventText("订阅自动续签").Click(new UIClick(request, "Model", "Recharge", "Code", hash["root"] as string)).Style(new UIStyle().BgColor()));
|
|
|
break;
|
|
|
}
|
|
|
ui.SendTo(this.Context, $"{request.Model}.{request.Command}");
|
|
|
});
|
|
|
|
|
|
switch (certmodel)
|
|
|
{
|
|
|
case "verifing":
|
|
|
var json = webr2.Post(new WebMeta().Put("type", "verify", "domain", host)).ReadAsString();
|
|
|
var hash = JSON.Deserialize<WebMeta>(json);
|
|
|
if (String.Equals(hash?["code"], "success") == false)
|
|
|
{
|
|
|
this.Prompt(hash["msg"]);
|
|
|
}
|
|
|
break;
|
|
|
case "check":
|
|
|
webr2.Post(new WebMeta().Put("type", "cert", "domain", host), Utility.Certificate);
|
|
|
break;
|
|
|
}
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
}
|
|
|
break;
|
|
|
case "Http":
|
|
|
var httpPort = UIDialog.AsyncDialog(this.Context, "Port", g =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "Http服务" };
|
|
|
fm.AddNumber("端口", "Port", String.Empty);
|
|
|
fm.Submit("确认", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
if (Utility.IntParse(httpPort, 0) > 0)
|
|
|
{
|
|
|
var p = UMC.Data.Provider.Create(httpPort, "http");
|
|
|
p.Attributes["port"] = httpPort;
|
|
|
hosts.Add(p);
|
|
|
UMC.Data.Reflection.Configuration("host", hosts);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
this.Prompt("请输入正确的端口号");
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case "Recharge":
|
|
|
{
|
|
|
var Code = UIDialog.AsyncDialog(this.Context, "Code", g =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "域名" };
|
|
|
fm.AddText("域名", "Code", String.Empty);
|
|
|
return fm;
|
|
|
});
|
|
|
var ComboValue = UMC.Web.UIDialog.AsyncDialog(this.Context, "Combo", gg =>
|
|
|
{
|
|
|
var webr = new Uri(APIProxy.Uri, "Transfer").WebRequest();
|
|
|
|
|
|
var secret = UMC.Data.WebResource.Instance().Provider["appSecret"];
|
|
|
UMC.ITME.Utility.Sign(webr, secret);
|
|
|
var data = JSON.Deserialize<WebMeta>(webr.Post(new WebMeta().Put("type", "Cert").Put("code", Code)).ReadAsString());
|
|
|
|
|
|
request.Arguments["API"] = data["src"] as string;
|
|
|
var Combo = data.GetDictionary()[gg] as Array;
|
|
|
|
|
|
var fom = new Web.UIFormDialog() { Title = data["Title"] ?? "订阅" };
|
|
|
var style = new UIStyle();
|
|
|
style.Name("icon").Color(0x09bb07).Size(84).Font("wdk");
|
|
|
style.Name("title").Color(0x333).Size(20);
|
|
|
style.BgColor(0xfafcff).Height(200).AlignCenter();
|
|
|
var desc = new UMC.Web.WebMeta().Put("title", data["Desc"] ?? "证书自动续签服务").Put("icon", data["Icon"] ?? "\uf0ee");
|
|
|
fom.Config.Put("Header", new UIHeader().Desc(desc, "{icon}\n{title}", style));
|
|
|
|
|
|
if (data.ContainsKey("Text"))
|
|
|
{
|
|
|
fom.AddTextValue().Put("订阅域名", data["Text"] as string ?? Code);
|
|
|
}
|
|
|
var f = fom.AddRadio("订阅套餐", "Combo");
|
|
|
var cl = Combo.Length;
|
|
|
for (var i = 0; i < cl; i++)
|
|
|
{
|
|
|
var hash = Combo.GetValue(i) as System.Collections.Hashtable;
|
|
|
f.Put(hash["Text"] as string, hash["Value"] as string, i == cl - 1);
|
|
|
}
|
|
|
fom.Config.Put("Action", true);
|
|
|
if (data.ContainsKey("Footer"))
|
|
|
{
|
|
|
fom.AddFooter(data["Footer"]);
|
|
|
}
|
|
|
|
|
|
fom.Submit("确认订阅");
|
|
|
return fom;
|
|
|
});
|
|
|
var src = this.AsyncDialog("API", r =>
|
|
|
{
|
|
|
this.Prompt("支付参数不正确,请联系官方");
|
|
|
});
|
|
|
response.Redirect(new Uri($"{src}&Combo={ComboValue}&Code={Code}"));
|
|
|
}
|
|
|
break;
|
|
|
case "Tcp":
|
|
|
|
|
|
var Tcp = this.AsyncDialog("TCP", g =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "TCP报文转发" };
|
|
|
fm.AddNumber("本地端口", "Port", String.Empty);
|
|
|
|
|
|
fm.AddText("服务端口", "Server", String.Empty).PlaceHolder("例如 192.0.0.2:22");
|
|
|
fm.Submit("确认", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
|
|
|
if (Utility.IntParse(Tcp["Port"], 0) > 0)
|
|
|
{
|
|
|
var server = Tcp["Server"].Split(":");
|
|
|
if (server.Length != 2)
|
|
|
{
|
|
|
this.Prompt("请输入正确的服务端口");
|
|
|
}
|
|
|
//(\d{1,3}\.){3}\d{1,3}
|
|
|
|
|
|
if (Utility.IntParse(server[1], 0) <= 0 || System.Text.RegularExpressions.Regex.IsMatch(server[0], @"(((\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))") == false)
|
|
|
{
|
|
|
|
|
|
this.Prompt("请输入正确的服务端口");
|
|
|
}
|
|
|
|
|
|
var p = UMC.Data.Provider.Create(Tcp["Port"], "tcp");
|
|
|
p.Attributes["port"] = Tcp["Port"];
|
|
|
p.Attributes["server"] = Tcp["Server"];
|
|
|
hosts.Add(p);
|
|
|
UMC.Data.Reflection.Configuration("host", hosts);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
this.Prompt("请输入正确的本地端口");
|
|
|
}
|
|
|
break;
|
|
|
case "Udp":
|
|
|
|
|
|
var udp = this.AsyncDialog("UDP", g =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "UDP报文转发" };
|
|
|
fm.AddNumber("本地端口", "Port", String.Empty);
|
|
|
|
|
|
fm.AddText("服务端口", "Server", String.Empty).PlaceHolder("例如 192.0.0.2:22");
|
|
|
fm.Submit("确认", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
|
|
|
if (Utility.IntParse(udp["Port"], 0) > 0)
|
|
|
{
|
|
|
var server = udp["Server"].Split(":");
|
|
|
if (server.Length != 2)
|
|
|
{
|
|
|
this.Prompt("请输入正确的服务端口");
|
|
|
}
|
|
|
|
|
|
if (Utility.IntParse(server[1], 0) <= 0 || System.Text.RegularExpressions.Regex.IsMatch(server[0], @"(((\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))") == false)
|
|
|
{
|
|
|
|
|
|
this.Prompt("请输入正确的服务端口");
|
|
|
}
|
|
|
|
|
|
var p = UMC.Data.Provider.Create(udp["Port"], "udp");
|
|
|
p.Attributes["port"] = p.Name;
|
|
|
p.Attributes["server"] = udp["Server"];
|
|
|
hosts.Add(p);
|
|
|
UMC.Data.Reflection.Configuration("host", hosts);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
this.Prompt("请输入正确的本地端口");
|
|
|
}
|
|
|
break;
|
|
|
case "Https":
|
|
|
|
|
|
var httpsPort = UIDialog.AsyncDialog(this.Context, "Port", g =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "Https服务" };
|
|
|
fm.AddNumber("端口", "Port", String.Empty);
|
|
|
fm.Submit("确认", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
if (Utility.IntParse(httpsPort, 0) > 0)
|
|
|
{
|
|
|
var p = UMC.Data.Provider.Create(httpsPort, "https");
|
|
|
p.Attributes["port"] = httpsPort;
|
|
|
|
|
|
hosts.Add(p);
|
|
|
UMC.Data.Reflection.Configuration("host", hosts);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
this.Prompt("请输入正确的端口号");
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case "PrivateKey":
|
|
|
{
|
|
|
var host = this.AsyncDialog("Domain", g => this.Prompt("请输入域名"));
|
|
|
var privateKey = UIDialog.AsyncDialog(this.Context, "PrivateKey", r =>
|
|
|
{
|
|
|
var fm = new UIFormDialog() { Title = "证书私钥" };
|
|
|
fm.AddTextValue().Put("域名", host);
|
|
|
fm.AddTextarea("私钥", "PrivateKey", String.Empty).PlaceHolder("证书.key文件内容").Put("tip", "证书私钥"); ;
|
|
|
fm.Submit("确认导入", $"{request.Model}.{request.Command}");
|
|
|
return fm;
|
|
|
});
|
|
|
|
|
|
var webr2 = new Uri(APIProxy.Uri, "Certificater").WebRequest();
|
|
|
|
|
|
var rese = UMC.ITME.Utility.Sign(webr2, UMC.Data.WebResource.Instance().Provider["appSecret"])
|
|
|
.Post(new WebMeta().Put("type", "cert", "domain", host));
|
|
|
if (rese.StatusCode != System.Net.HttpStatusCode.OK)
|
|
|
{
|
|
|
this.Prompt("提示", rese.ReadAsString());
|
|
|
}
|
|
|
var json = rese.ReadAsString();
|
|
|
|
|
|
var cert = JSON.Deserialize<WebMeta>(json);
|
|
|
var domain = cert["domain"];
|
|
|
var publicKey = cert["publicKey"];
|
|
|
try
|
|
|
{
|
|
|
var x509 = X509Certificate2.CreateFromPem(publicKey, privateKey);
|
|
|
var p = UMC.Data.Provider.Create(domain, "privateKey");
|
|
|
p.Attributes["publicKey"] = publicKey;
|
|
|
p.Attributes["privateKey"] = privateKey;
|
|
|
var certs = UMC.Data.Reflection.Configuration("certs");
|
|
|
certs.Add(p);
|
|
|
Certificater.Certificates[p.Name] = new Certificater { Name = p.Name, Certificate = x509 };
|
|
|
UMC.Data.Reflection.Configuration("certs", certs);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
this.Prompt("证书错误", ex.Message);
|
|
|
}
|
|
|
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
|
|
|
var pr = hosts[model];
|
|
|
if (pr != null)
|
|
|
{
|
|
|
hosts.Remove(model);
|
|
|
UMC.Data.Reflection.Configuration("host", hosts);
|
|
|
this.Context.Send($"{request.Model}.{request.Command}", true);
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
} |