mirror of
https://github.com/Bubuni-Team/telegram-bot.git
synced 2026-07-31 00:29:24 +03:00
add Uri parser, add ISerializationBinder
ISerializationBinder is added only in whitelist mode. Types for whitelisting should be registered manually via new API `Module.StartAsync()` or attribute `AllowedSerializableType(name)`
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core.Attributes
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public class AllowedSerializableTypeAttribute : Attribute
|
||||||
|
{
|
||||||
|
public readonly string Name;
|
||||||
|
public AllowedSerializableTypeAttribute(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -14,7 +14,7 @@ public sealed class Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Core API version.
|
/// The Core API version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UInt32 ApiVersion => 1;
|
public UInt32 ApiVersion => 2;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The array that contains all modules instances.
|
/// The array that contains all modules instances.
|
||||||
|
|||||||
+6
-1
@@ -2,6 +2,8 @@
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Kruzya.TelegramBot.Core;
|
namespace Kruzya.TelegramBot.Core;
|
||||||
|
|
||||||
@@ -22,7 +24,10 @@ public abstract class Module
|
|||||||
public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual Task StartAsync(CancellationToken cts, IServiceScope scope) => Task.CompletedTask;
|
||||||
|
public virtual Task StopAsync(CancellationToken cts, IServiceScope scope) => Task.CompletedTask;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ensures if module is loaded and started. Note that call can change module event chain.
|
/// Ensures if module is loaded and started. Note that call can change module event chain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core
|
||||||
|
{
|
||||||
|
public class SerializationBinder : ISerializationBinder
|
||||||
|
{
|
||||||
|
protected IDictionary<string, Type> _allowedTypes = new Dictionary<string, Type>();
|
||||||
|
|
||||||
|
public void RegisterAllowedType(string name, Type type)
|
||||||
|
{
|
||||||
|
if (_allowedTypes.ContainsKey(name))
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"{name} is already registered", "name");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var knownType in _allowedTypes.Values)
|
||||||
|
{
|
||||||
|
if (type != knownType)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException($"{type.FullName} is already known type", "type");
|
||||||
|
}
|
||||||
|
|
||||||
|
_allowedTypes.Add(name, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterAllowedType<T>(string name) where T : class
|
||||||
|
{
|
||||||
|
RegisterAllowedType(name, typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
|
||||||
|
{
|
||||||
|
assemblyName = null;
|
||||||
|
typeName = _allowedTypes.Where(x => x.Value == serializedType)
|
||||||
|
.FirstOrDefault().Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type BindToType(string assemblyName, string typeName)
|
||||||
|
{
|
||||||
|
return _allowedTypes[typeName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using Castle.Core.Internal;
|
||||||
|
using Kruzya.TelegramBot.Core.Attributes;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core.Service
|
||||||
|
{
|
||||||
|
public class CoreManager : IHostedService
|
||||||
|
{
|
||||||
|
private readonly Core _core;
|
||||||
|
private readonly IServiceScopeFactory _scopeFactory;
|
||||||
|
|
||||||
|
public CoreManager(Core core, IServiceScopeFactory scopeFactory)
|
||||||
|
{
|
||||||
|
_core = core;
|
||||||
|
_scopeFactory = scopeFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartAsync(CancellationToken cts)
|
||||||
|
{
|
||||||
|
await ManagerStartAsync(cts, _scopeFactory.CreateScope());
|
||||||
|
foreach (var module in _core.Modules)
|
||||||
|
{
|
||||||
|
await module.StartAsync(cts, _scopeFactory.CreateScope());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopAsync(CancellationToken cts)
|
||||||
|
{
|
||||||
|
// await ManagerStopAsync(cts, _scopeFactory.CreateScope());
|
||||||
|
foreach (var module in _core.Modules)
|
||||||
|
{
|
||||||
|
await module.StopAsync(cts, _scopeFactory.CreateScope());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ManagerStartAsync(CancellationToken cts, IServiceScope scope)
|
||||||
|
{
|
||||||
|
var binder = scope.ServiceProvider.GetRequiredService<SerializationBinder>();
|
||||||
|
var allowedSerializationTypes = _core.Modules
|
||||||
|
.SelectMany(module => module.GetType().Assembly.ExportedTypes)
|
||||||
|
.Where(definedType => definedType.GetAttribute<AllowedSerializableTypeAttribute>() != null)
|
||||||
|
.ToDictionary(type => type.GetAttribute<AllowedSerializableTypeAttribute>().Name);
|
||||||
|
|
||||||
|
foreach (var pair in allowedSerializationTypes)
|
||||||
|
{
|
||||||
|
binder.RegisterAllowedType(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@ using System.Collections.Concurrent;
|
|||||||
using Kruzya.TelegramBot.Core.Options;
|
using Kruzya.TelegramBot.Core.Options;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using BotFramework.Abstractions.UpdateProvider;
|
using BotFramework.Abstractions.UpdateProvider;
|
||||||
|
using System;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
namespace Kruzya.TelegramBot.Core;
|
namespace Kruzya.TelegramBot.Core;
|
||||||
|
|
||||||
@@ -55,11 +57,15 @@ public class Startup
|
|||||||
|
|
||||||
services.AddSingleton<ConcurrentBag<DeleteRequest>>();
|
services.AddSingleton<ConcurrentBag<DeleteRequest>>();
|
||||||
services.AddHostedService<DeleteService>();
|
services.AddHostedService<DeleteService>();
|
||||||
|
services.AddHostedService<CoreManager>();
|
||||||
|
|
||||||
services.AddScoped<IOptionProvider, DbOptionProvider>();
|
services.AddScoped<IOptionProvider, DbOptionProvider>();
|
||||||
services.AddHttpClient();
|
services.AddHttpClient();
|
||||||
|
|
||||||
|
services.AddTelegramBotParameterParser<Uri, AbsoluteUriParser>();
|
||||||
|
|
||||||
services.AddSingleton<Hash>();
|
services.AddSingleton<Hash>();
|
||||||
|
services.AddSingleton<ISerializationBinder, SerializationBinder>();
|
||||||
|
|
||||||
// Trigger module handlers.
|
// Trigger module handlers.
|
||||||
_core.Modules.ConfigureServices(services);
|
_core.Modules.ConfigureServices(services);
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using BotFramework;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core
|
||||||
|
{
|
||||||
|
public class AbsoluteUriParser : IParameterParser<Uri>
|
||||||
|
{
|
||||||
|
public Uri DefaultInstance() => null;
|
||||||
|
|
||||||
|
public bool TryGetValue(string text, out Uri result)
|
||||||
|
{
|
||||||
|
return Uri.TryCreate(text, UriKind.Absolute, out result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user