2023-09-21 03:49:27 +08:00
|
|
|
using Godot;
|
|
|
|
using System;
|
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Net;
|
|
|
|
using System.Net.Http;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Web;
|
|
|
|
using BITKit;
|
|
|
|
using BITKit.Auth;
|
|
|
|
using BITKit.Net.Http;
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
using Environment = System.Environment;
|
|
|
|
using HttpClient = System.Net.Http.HttpClient;
|
|
|
|
|
|
|
|
namespace IDIS.License;
|
|
|
|
|
|
|
|
public class LicenseBin
|
|
|
|
{
|
|
|
|
public DateTime ExpirationDate=DateTime.Now;
|
|
|
|
public string Token;
|
|
|
|
}
|
|
|
|
public partial class LicenseService : EntityComponent,IAuthService
|
|
|
|
{
|
|
|
|
private static readonly HttpClient _httpClient = new();
|
|
|
|
[Export] private string _requestAuthorizeUrl;
|
|
|
|
[Export] private string _revokeAuthorizeUrl;
|
|
|
|
public bool IsAuthorized { get;private set; }
|
|
|
|
public bool IsAuthorizing { get;private set; }
|
|
|
|
|
|
|
|
public event Action<string> OnAuthorize;
|
|
|
|
public event Action<string> OnAuthorized;
|
|
|
|
public event Action<string> UnAuthorize;
|
|
|
|
public event Action<string> OnAuthorizeFailure;
|
|
|
|
|
|
|
|
private CancellationTokenSource _cancellationTokenSource;
|
|
|
|
private CancellationToken _cancellationToken=>_cancellationTokenSource.Token;
|
|
|
|
private IHttpListenerService _httpListenerService;
|
|
|
|
private readonly string path = Path.Combine(
|
|
|
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
|
|
|
"iFactory",
|
|
|
|
"License.bin"
|
|
|
|
);
|
|
|
|
|
|
|
|
public override void BuildService(IServiceCollection serviceCollection)
|
|
|
|
{
|
|
|
|
serviceCollection.AddSingleton<IAuthService>(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void _EnterTree()
|
|
|
|
{
|
|
|
|
_cancellationTokenSource = new CancellationTokenSource();
|
|
|
|
}
|
|
|
|
public override void _ExitTree()
|
|
|
|
{
|
|
|
|
_cancellationTokenSource.Cancel();
|
|
|
|
}
|
|
|
|
public override void OnAwake()
|
|
|
|
{
|
|
|
|
_httpListenerService = Entity.ServiceProvider.GetRequiredService<IHttpListenerService>();
|
|
|
|
_httpListenerService.OnRequest += OnRequest;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void OnStart()
|
|
|
|
{
|
|
|
|
BIT4Log.Log<LicenseService>("准备文件中,二进制授权文件路径:"+path);
|
|
|
|
if (IsAuthorized || IsAuthorizing) return;
|
|
|
|
if (File.Exists(path) is false) return;
|
|
|
|
var json = File.ReadAllText(path);
|
|
|
|
var licenseBin = JsonConvert.DeserializeObject<LicenseBin>(json);
|
|
|
|
if(licenseBin.ExpirationDate<DateTime.Now) return;
|
|
|
|
AuthorizeAsync(licenseBin.Token).Forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
private HttpContent OnRequest(HttpListenerRequest arg)
|
|
|
|
{
|
2023-09-23 23:01:39 +08:00
|
|
|
//if (arg.HttpMethod is not "POST" or not "OPTIONS") return new StringContent(ContextModel.Error("Method Not Allowed"));
|
|
|
|
var sr = new StreamReader(arg.InputStream);
|
|
|
|
var token = sr.ReadToEnd();
|
2023-09-21 03:49:27 +08:00
|
|
|
AuthorizeAsync(token).Forget();
|
2023-09-23 23:01:39 +08:00
|
|
|
return new StringContent(ContextModel.Get(true));
|
2023-09-21 03:49:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public async UniTask AuthorizeAsync(string token)
|
|
|
|
{
|
|
|
|
OnAuthorize?.Invoke(token);
|
2023-09-23 23:01:39 +08:00
|
|
|
var response = await _httpClient.PostAsync(_requestAuthorizeUrl,new StringContent( JsonConvert.SerializeObject(token),Encoding.UTF8, "application/json"), _cancellationToken);
|
2023-09-21 03:49:27 +08:00
|
|
|
var message = await response.Content.ReadAsStringAsync(_cancellationToken);
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
|
|
{
|
|
|
|
OnAuthorized?.Invoke(message);
|
|
|
|
BIT4Log.Log<IAuthService>($"授权成功:{message}");
|
|
|
|
var licenseBin = new LicenseBin
|
|
|
|
{
|
2023-09-23 23:01:39 +08:00
|
|
|
Token = token,
|
2023-09-21 03:49:27 +08:00
|
|
|
ExpirationDate = DateTime.Now.AddDays(7)
|
|
|
|
};
|
|
|
|
PathHelper.EnsureDirectoryCreated(path);
|
|
|
|
await File.WriteAllTextAsync(path, JsonConvert.SerializeObject(licenseBin), _cancellationToken);
|
|
|
|
IsAuthorized = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OnAuthorizeFailure?.Invoke(message);
|
2023-09-23 23:01:39 +08:00
|
|
|
BIT4Log.Log<IAuthService>($"当前Token:{token}");
|
2023-09-21 03:49:27 +08:00
|
|
|
BIT4Log.Log<IAuthService>($"授权失败:{message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public UniTask CancelAuthorizationAsync()
|
|
|
|
{
|
|
|
|
if (IsAuthorized is false)
|
|
|
|
{
|
|
|
|
throw new InvalidOperationException("未授权");
|
|
|
|
}
|
|
|
|
var url = _revokeAuthorizeUrl.Replace("{x}",_requestAuthorizeUrl);
|
|
|
|
UnAuthorize?.Invoke("取消授权");
|
|
|
|
IsAuthorized = false;
|
|
|
|
_httpClient.PostAsync(url, new StringContent(""), _cancellationToken).AsUniTask().Forget();
|
|
|
|
return UniTask.CompletedTask;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|