Change project to 3-Layer structure

This commit is contained in:
Tech Garage 2023-06-02 15:26:29 +03:30
parent 2f900a5036
commit 2d67540e13
1365 changed files with 760 additions and 618 deletions

View file

@ -0,0 +1,33 @@
using Microsoft.Extensions.DependencyInjection;
using MTWireGuard;
using MTWireGuard.Application.Mapper;
using MTWireGuard.Application.Repositories;
using MTWireGuard.Application.Services;
using System.Reflection;
namespace MTWireGuard.Application
{
public static class ApplicationServiceRegister
{
public static void AddApplicationServices(this IServiceCollection services)
{
// Add DBContext
services.AddDbContext<DBContext>(ServiceLifetime.Singleton);
// Auto Mapper Configurations
services.AddSingleton<PeerMapping>();
services.AddSingleton<ServerMapping>();
services.AddSingleton<MappingProfile>();
services.AddAutoMapper(
(provider, expression) => {
expression.AddProfile(provider.GetService<PeerMapping>());
expression.AddProfile(provider.GetService<ServerMapping>());
expression.AddProfile(provider.GetService<MappingProfile>());
},
new List<Assembly>());
// Add Mikrotik API Service
services.AddSingleton<IMikrotikRepository, MTAPI>();
}
}
}

View file

@ -1,8 +1,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting; using MTWireGuard.Application.Models.Mikrotik;
using MTWireGuard.Models.Mikrotik;
namespace MTWireGuard namespace MTWireGuard.Application
{ {
public class DBContext : DbContext public class DBContext : DbContext
{ {

View file

@ -1,11 +1,8 @@
using MTWireGuard.Models.Mikrotik; using System.IO.Compression;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO.Compression;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace MTWireGuard namespace MTWireGuard.Application
{ {
public class Helper public class Helper
{ {

View file

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageReference Include="QRCoder" Version="1.4.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MikrotikAPI\MikrotikAPI.csproj" />
</ItemGroup>
</Project>

View file

@ -1,24 +1,22 @@
using AutoMapper; using AutoMapper;
using Microsoft.EntityFrameworkCore; using MTWireGuard.Application.Models.Mikrotik;
using MTWireGuard.Models;
using MTWireGuard.Models.Mikrotik;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace MTWireGuard.Mapper namespace MTWireGuard.Application.Mapper
{ {
public class MappingProfile : Profile public class MappingProfile : Profile
{ {
public MappingProfile() public MappingProfile()
{ {
// Logs // Logs
CreateMap<Log, LogViewModel>() CreateMap<MikrotikAPI.Models.Log, LogViewModel>()
.ForMember(dest => dest.Id, .ForMember(dest => dest.Id,
opt => opt.MapFrom(src => Convert.ToUInt64(src.Id.Substring(1), 16))) opt => opt.MapFrom(src => Convert.ToUInt64(src.Id.Substring(1), 16)))
.ForMember(dest =>dest.Topics, .ForMember(dest =>dest.Topics,
opt => opt.MapFrom(src => FormatTopics(src.Topics))); opt => opt.MapFrom(src => FormatTopics(src.Topics)));
// Server Traffic // Server Traffic
CreateMap<ServerTraffic, ServerTrafficViewModel>() CreateMap<MikrotikAPI.Models.ServerTraffic, ServerTrafficViewModel>()
.ForMember(dest => dest.Name, .ForMember(dest => dest.Name,
opt => opt.MapFrom(src => src.Name)) opt => opt.MapFrom(src => src.Name))
.ForMember(dest => dest.Type, .ForMember(dest => dest.Type,
@ -33,7 +31,7 @@ namespace MTWireGuard.Mapper
opt => opt.MapFrom(src => Convert.ToInt64(src.RX))); opt => opt.MapFrom(src => Convert.ToInt64(src.RX)));
// Mikrotik HWInfo // Mikrotik HWInfo
CreateMap<MTInfo, MTInfoViewModel>() CreateMap<MikrotikAPI.Models.MTInfo, MTInfoViewModel>()
.ForMember(dest => dest.Architecture, .ForMember(dest => dest.Architecture,
opt => opt.MapFrom(src => src.ArchitectureName)) opt => opt.MapFrom(src => src.ArchitectureName))
.ForMember(dest => dest.CPUCount, .ForMember(dest => dest.CPUCount,
@ -74,32 +72,23 @@ namespace MTWireGuard.Mapper
opt => opt.MapFrom(src => FormatUptime(src.Uptime))); opt => opt.MapFrom(src => FormatUptime(src.Uptime)));
// Router Identity // Router Identity
CreateMap<MTIdentity, MTIdentityViewModel>(); CreateMap<MikrotikAPI.Models.MTIdentity, MTIdentityViewModel>();
// Active Users // Active Users
CreateMap<ActiveUser, ActiveUserViewModel>() CreateMap<MikrotikAPI.Models.ActiveUser, ActiveUserViewModel>()
.ForMember(dest => dest.Id, .ForMember(dest => dest.Id,
opt => opt.MapFrom(src => Convert.ToInt16(src.Id.Substring(1), 16))) opt => opt.MapFrom(src => Convert.ToInt16(src.Id.Substring(1), 16)))
.ForMember(dest => dest.LoggedIn, .ForMember(dest => dest.LoggedIn,
opt => opt.MapFrom(src => src.When)); opt => opt.MapFrom(src => src.When));
// Active Jobs // Active Jobs
CreateMap<Job, JobViewModel>() CreateMap<MikrotikAPI.Models.Job, JobViewModel>()
.ForMember(dest => dest.Id, .ForMember(dest => dest.Id,
opt => opt.MapFrom(src => Convert.ToInt16(src.Id.Substring(1), 16))) opt => opt.MapFrom(src => Convert.ToInt16(src.Id.Substring(1), 16)))
.ForMember(dest => dest.NextId, .ForMember(dest => dest.NextId,
opt => opt.MapFrom(src => Convert.ToInt16(src.NextId.Substring(1), 16))) opt => opt.MapFrom(src => Convert.ToInt16(src.NextId.Substring(1), 16)))
.ForMember(dest => dest.Policies, .ForMember(dest => dest.Policies,
opt => opt.MapFrom(src => src.Policy.Split(',', StringSplitOptions.None).ToList())); opt => opt.MapFrom(src => src.Policy.Split(',', StringSplitOptions.None).ToList()));
// Item Creation
CreateMap<CreationStatus, CreationResult>()
.ForMember(dest => dest.Code,
opt => opt.MapFrom(src => (src.Success) ? "200" : src.Code.ToString()))
.ForMember(dest => dest.Title,
opt => opt.MapFrom(src => (src.Success) ? "Done" : src.Message))
.ForMember(dest => dest.Description,
opt => opt.MapFrom(src => (src.Success) ? "Item created/updated successfully." : src.Detail));
} }
private static List<string> FormatTopics(string topics) private static List<string> FormatTopics(string topics)

View file

@ -1,16 +1,18 @@
using AutoMapper; using AutoMapper;
using MTWireGuard.Models.Mikrotik; using Microsoft.Extensions.DependencyInjection;
using MTWireGuard.Models.Requests; using MikrotikAPI.Models;
using MTWireGuard.Application.Models.Mikrotik;
namespace MTWireGuard.Mapper namespace MTWireGuard.Application.Mapper
{ {
public class PeerMapping : Profile public class PeerMapping : Profile
{ {
DBContext db; private readonly IServiceProvider _provider;
public PeerMapping(DBContext context) private IServiceProvider Provider => _provider.CreateScope().ServiceProvider;
{
db = context;
public PeerMapping(IServiceProvider provider)
{
_provider = provider;
/* /*
* Mikrotik Peer to ViewModel * Mikrotik Peer to ViewModel
*/ */
@ -44,19 +46,6 @@ namespace MTWireGuard.Mapper
CreateMap<UserUpdateModel, WGPeerUpdateModel>() CreateMap<UserUpdateModel, WGPeerUpdateModel>()
.ForMember(dest => dest.Id, .ForMember(dest => dest.Id,
opt => opt.MapFrom(src => $"*{src.Id:X}")); opt => opt.MapFrom(src => $"*{src.Id:X}"));
CreateMap<CreateClientRequest, UserCreateModel>()
.ForMember(dest => dest.Disabled,
opt => opt.MapFrom(src => !src.Enabled))
.ForMember(dest => dest.EndpointAddress,
opt => opt.MapFrom(src => src.Endpoint))
.ForMember(dest => dest.PersistentKeepalive,
opt => opt.MapFrom(src => src.KeepAlive.ToString()));
CreateMap<SyncUserRequest, UserSyncModel>();
CreateMap<UpdateClientRequest, UserUpdateModel>()
.ForMember(dest => dest.EndpointAddress,
opt => opt.MapFrom(src => src.Endpoint))
.ForMember(dest => dest.PersistentKeepalive,
opt => opt.MapFrom(src => src.KeepAlive));
// DBUser // DBUser
CreateMap<WGPeerViewModel, WGPeerDBModel>(); CreateMap<WGPeerViewModel, WGPeerDBModel>();
@ -69,16 +58,19 @@ namespace MTWireGuard.Mapper
private string? GetPeerName(WGPeer source) private string? GetPeerName(WGPeer source)
{ {
var db = Provider.GetService<DBContext>();
return (db.Users.ToList().Find(u => u.Id == Convert.ToInt32(source.Id[1..], 16)) != null) ? db.Users.ToList().Find(u => u.Id == Convert.ToInt32(source.Id[1..], 16)).Name : ""; return (db.Users.ToList().Find(u => u.Id == Convert.ToInt32(source.Id[1..], 16)) != null) ? db.Users.ToList().Find(u => u.Id == Convert.ToInt32(source.Id[1..], 16)).Name : "";
} }
private string? GetPeerPrivateKey(WGPeer source) private string? GetPeerPrivateKey(WGPeer source)
{ {
var db = Provider.GetService<DBContext>();
return (db.Users.ToList().Find(u => u.Id == Convert.ToInt32(source.Id[1..], 16)) != null) ? db.Users.ToList().Find(u => u.Id == Convert.ToInt32(source.Id[1..], 16)).PrivateKey : ""; return (db.Users.ToList().Find(u => u.Id == Convert.ToInt32(source.Id[1..], 16)) != null) ? db.Users.ToList().Find(u => u.Id == Convert.ToInt32(source.Id[1..], 16)).PrivateKey : "";
} }
private bool HasDifferences(WGPeer source) private bool HasDifferences(WGPeer source)
{ {
var db = Provider.GetService<DBContext>();
var id = Convert.ToInt32(source.Id[1..], 16); var id = Convert.ToInt32(source.Id[1..], 16);
var dbUser = db.Users.ToList().Find(x => x.Id == id); var dbUser = db.Users.ToList().Find(x => x.Id == id);
if (dbUser is null) return true; if (dbUser is null) return true;

View file

@ -1,8 +1,7 @@
using AutoMapper; using AutoMapper;
using MTWireGuard.Models.Mikrotik; using MTWireGuard.Application.Models.Mikrotik;
using MTWireGuard.Models.Requests;
namespace MTWireGuard.Mapper namespace MTWireGuard.Application.Mapper
{ {
public class ServerMapping : Profile public class ServerMapping : Profile
{ {
@ -11,7 +10,7 @@ namespace MTWireGuard.Mapper
/* /*
* Convert Mikrotik Server Model to ViewModel * Convert Mikrotik Server Model to ViewModel
*/ */
CreateMap<WGServer, WGServerViewModel>() CreateMap<MikrotikAPI.Models.WGServer, WGServerViewModel>()
.ForMember(dest => dest.Id, .ForMember(dest => dest.Id,
opt => opt.MapFrom(src => Convert.ToInt32(src.Id.Substring(1), 16))) opt => opt.MapFrom(src => Convert.ToInt32(src.Id.Substring(1), 16)))
.ForMember(dest => dest.IsEnabled, .ForMember(dest => dest.IsEnabled,
@ -20,23 +19,14 @@ namespace MTWireGuard.Mapper
/* /*
* Convert Wrapper CreateModel to Rest-API CreateModel * Convert Wrapper CreateModel to Rest-API CreateModel
*/ */
CreateMap<CreateServerRequest, ServerCreateModel>() CreateMap<ServerCreateModel, MikrotikAPI.Models.WGServerCreateModel>()
.ForMember(dest => dest.ListenPort,
opt => opt.MapFrom(src => src.Port));
CreateMap<ServerCreateModel, WGServerCreateModel>()
.ForMember(dest => dest.Disabled, .ForMember(dest => dest.Disabled,
opt => opt.MapFrom(src => !src.Enabled)); opt => opt.MapFrom(src => !src.Enabled));
/* /*
* Convert Wrapper UpdateModel to Rest-API UpdateModel * Convert Wrapper UpdateModel to Rest-API UpdateModel
*/ */
CreateMap<UpdateServerRequest, ServerUpdateModel>() CreateMap<ServerUpdateModel, MikrotikAPI.Models.WGServerUpdateModel>()
.ForMember(dest => dest.ListenPort,
opt => opt.MapFrom(src => src.Port));
CreateMap<ServerUpdateModel, WGServerUpdateModel>()
.ForMember(dest => dest.Id, .ForMember(dest => dest.Id,
opt => opt.MapFrom(src => $"*{src.Id:X}")); opt => opt.MapFrom(src => $"*{src.Id:X}"));
} }

View file

@ -7,7 +7,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable #nullable disable
namespace MTWireGuard.Migrations namespace MTWireGuard.Application.Migrations
{ {
[DbContext(typeof(DBContext))] [DbContext(typeof(DBContext))]
[Migration("20230108171012_Initialize")] [Migration("20230108171012_Initialize")]

View file

@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace MTWireGuard.Migrations namespace MTWireGuard.Application.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class Initialize : Migration public partial class Initialize : Migration

View file

@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable #nullable disable
namespace MTWireGuard.Migrations namespace MTWireGuard.Application.Migrations
{ {
[DbContext(typeof(DBContext))] [DbContext(typeof(DBContext))]
partial class DBContextModelSnapshot : ModelSnapshot partial class DBContextModelSnapshot : ModelSnapshot

View file

@ -0,0 +1,10 @@
namespace MTWireGuard.Application.Models
{
public class CreationResult
{
public string Code { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
}

View file

@ -0,0 +1,14 @@
using Newtonsoft.Json;
namespace MTWireGuard.Application.Models.Mikrotik
{
public class ActiveUserViewModel
{
public short Id { get; set; }
public string Group { get; set; }
public string Name { get; set; }
public bool Radius { get; set; }
public string Via { get; set; }
public string LoggedIn { get; set; }
}
}

View file

@ -0,0 +1,7 @@
namespace MTWireGuard.Application.Models.Mikrotik
{
public class MTIdentityViewModel
{
public string Name { get; set; }
}
}

View file

@ -0,0 +1,14 @@
using Newtonsoft.Json;
namespace MTWireGuard.Application.Models.Mikrotik
{
public class JobViewModel
{
public short Id { get; set; }
public short NextId { get; set; }
public string Owner { get; set; }
public List<string> Policies { get; set; }
public string Started { get; set; }
public string Type { get; set; }
}
}

View file

@ -0,0 +1,10 @@
namespace MTWireGuard.Application.Models.Mikrotik
{
public class LogViewModel
{
public ulong Id { get; set; }
public string Message { get; set; }
public string Time { get; set; }
public List<string> Topics { get; set; }
}
}

View file

@ -0,0 +1,29 @@
namespace MTWireGuard.Application.Models.Mikrotik
{
public class MTInfoViewModel
{
public string Architecture { get; set; }
public string BoardName { get; set; }
public string Platform { get; set; }
public string CPU { get; set; }
public byte CPUCount { get; set; }
public short CPUFrequency { get; set; }
public byte CPULoad { get; set; }
public string TotalHDD { get; set; }
public string UsedHDD { get; set; }
public string FreeHDD { get; set; }
public long TotalHDDBytes { get; set; }
public long UsedHDDBytes { get; set; }
public long FreeHDDBytes { get; set; }
public byte FreeHDDPercentage { get; set; }
public string TotalRAM { get; set; }
public string UsedRAM { get; set; }
public string FreeRAM { get; set; }
public long TotalRAMBytes { get; set; }
public long UsedRAMBytes { get; set; }
public long FreeRAMBytes { get; set; }
public byte FreeRAMPercentage { get; set; }
public string UPTime { get; set; }
public string Version { get; set; }
}
}

View file

@ -0,0 +1,12 @@
namespace MTWireGuard.Application.Models.Mikrotik
{
public class ServerTrafficViewModel
{
public string Name { get; set; }
public string Type { get; set; }
public string Upload { get; set; }
public string Download { get; set; }
public long UploadBytes { get; set; }
public long DownloadBytes { get; set; }
}
}

View file

@ -0,0 +1,68 @@
using Microsoft.EntityFrameworkCore;
namespace MTWireGuard.Application.Models.Mikrotik
{
[PrimaryKey("Id")]
[Index("PrivateKey", IsUnique = true)]
[Index("PublicKey", IsUnique = true)]
public class WGPeerDBModel
{
public int Id { get; set; }
public string? Name { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
}
public class WGPeerViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string CurrentAddress { get; set; }
public bool IsEnabled { get; set; }
public string Interface { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
public string Download { get; set; }
public string Upload { get; set; }
public long DownloadBytes { get; set; }
public long UploadBytes { get; set; }
public bool IsDifferent { get; set; }
}
public class UserCreateModel
{
public string Name { get; set; }
public string PrivateKey { get; set; }
public string AllowedAddress { get; set; }
public bool Disabled { get; set; }
public string Interface { get; set; }
public string EndpointAddress { get; set; }
public string EndpointPort { get; set; }
public string PublicKey { get; set; }
public string PresharedKey { get; set; }
public string PersistentKeepalive { get; set; }
}
public class UserSyncModel
{
public int Id { get; set; }
public string Name { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
}
public class UserUpdateModel
{
public int Id { get; set; }
public string Name { get; set; }
public string AllowedAddress { get; set; }
public string Interface { get; set; }
public string EndpointAddress { get; set; }
public ushort EndpointPort { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
public string PresharedKey { get; set; }
public int PersistentKeepalive { get; set; }
}
}

View file

@ -0,0 +1,32 @@
namespace MTWireGuard.Application.Models.Mikrotik
{
public class WGServerViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsEnabled { get; set; }
public ushort ListenPort { get; set; }
public ushort MTU { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
public bool Running { get; set; }
}
public class ServerCreateModel
{
public string Name { get; set; }
public bool Enabled { get; set; }
public string ListenPort { get; set; }
public string MTU { get; set; }
public string PrivateKey { get; set; }
}
public class ServerUpdateModel
{
public int Id { get; set; }
public string Name { get; set; }
public ushort ListenPort { get; set; }
public ushort MTU { get; set; }
public string PrivateKey { get; set; }
}
}

View file

@ -0,0 +1,16 @@
namespace MTWireGuard.Application.Models
{
public class SidebarInfo
{
public int RAMUsedPercentage { get; set; }
public int CPUUsedPercentage { get; set; }
public int HDDUsedPercentage { get; set; }
public string RAMUsed { get; set; }
public string HDDUsed { get; set; }
public string TotalRAM { get; set; }
public string TotalHDD { get; set; }
public string RAMBgColor { get; set; }
public string CPUBgColor { get; set; }
public string HDDBgColor { get; set; }
}
}

View file

@ -1,7 +1,8 @@
using MTWireGuard.Models; using MTWireGuard.Application.Models;
using MTWireGuard.Models.Mikrotik; using MTWireGuard.Application.Models.Mikrotik;
using MikrotikAPI.Models;
namespace MTWireGuard.Repositories namespace MTWireGuard.Application.Repositories
{ {
public interface IMikrotikRepository : IDisposable public interface IMikrotikRepository : IDisposable
{ {

View file

@ -1,55 +1,58 @@
using AutoMapper; using AutoMapper;
using Microsoft.AspNetCore.Hosting.Server; using MikrotikAPI;
using Microsoft.EntityFrameworkCore; using MTWireGuard.Application.Models;
using MTWireGuard.Models; using MTWireGuard.Application.Models.Mikrotik;
using MTWireGuard.Models.Mikrotik; using MTWireGuard.Application.Repositories;
using MTWireGuard.Repositories;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QRCoder; using QRCoder;
namespace MTWireGuard.Services namespace MTWireGuard.Application.Services
{ {
public class MTAPI : IMikrotikRepository public class MTAPI : IMikrotikRepository
{ {
private readonly IMapper mapper; private readonly IMapper mapper;
private readonly DBContext dbContext; private readonly DBContext dbContext;
private readonly APIWrapper wrapper;
private bool disposed = false; private bool disposed = false;
public MTAPI(IMapper mapper, DBContext dbContext) public MTAPI(IMapper mapper, DBContext dbContext)
{ {
this.mapper = mapper; this.mapper = mapper;
this.dbContext = dbContext; this.dbContext = dbContext;
string MT_IP = Environment.GetEnvironmentVariable("MT_IP");
string MT_USER = Environment.GetEnvironmentVariable("MT_USER");
string MT_PASS = Environment.GetEnvironmentVariable("MT_PASS");
this.wrapper = new(MT_IP, MT_USER, MT_PASS);
} }
public async Task<List<LogViewModel>> GetLogsAsync() public async Task<List<LogViewModel>> GetLogsAsync()
{ {
var model = await APIHandler.GetLogsAsync(); var model = await wrapper.GetLogsAsync();
var result = mapper.Map<List<LogViewModel>>(model); var result = mapper.Map<List<LogViewModel>>(model);
return result.OrderBy(list => list.Id).ToList(); return result.OrderBy(list => list.Id).ToList();
} }
public async Task<List<WGServerViewModel>> GetServersAsync() public async Task<List<WGServerViewModel>> GetServersAsync()
{ {
var model = await APIHandler.GetServersAsync(); var model = await wrapper.GetServersAsync();
var result = mapper.Map<List<WGServerViewModel>>(model); var result = mapper.Map<List<WGServerViewModel>>(model);
return result.OrderBy(list => list.Id).ToList(); return result.OrderBy(list => list.Id).ToList();
} }
public async Task<WGServerViewModel> GetServer(string Name) public async Task<WGServerViewModel> GetServer(string Name)
{ {
var model = await APIHandler.GetServer(Name); var model = await wrapper.GetServer(Name);
return mapper.Map<WGServerViewModel>(model); return mapper.Map<WGServerViewModel>(model);
} }
public async Task<List<ServerTrafficViewModel>> GetServersTraffic() { public async Task<List<ServerTrafficViewModel>> GetServersTraffic() {
var model = await APIHandler.GetServersTraffic(); var model = await wrapper.GetServersTraffic();
return mapper.Map<List<ServerTrafficViewModel>>(model); return mapper.Map<List<ServerTrafficViewModel>>(model);
} }
public async Task<List<WGPeerViewModel>> GetUsersAsync() public async Task<List<WGPeerViewModel>> GetUsersAsync()
{ {
var model = await APIHandler.GetUsersAsync(); var model = await wrapper.GetUsersAsync();
var result = mapper.Map<List<WGPeerViewModel>>(model); var result = mapper.Map<List<WGPeerViewModel>>(model);
return result.OrderBy(list => list.Id).ToList(); return result.OrderBy(list => list.Id).ToList();
} }
public async Task<WGPeerViewModel> GetUser(int id) public async Task<WGPeerViewModel> GetUser(int id)
{ {
var model = await APIHandler.GetUser($"*{id:X}"); var model = await wrapper.GetUser($"*{id:X}");
return mapper.Map<WGPeerViewModel>(model); return mapper.Map<WGPeerViewModel>(model);
} }
public async Task<string> GetUserTunnelConfig(int id) public async Task<string> GetUserTunnelConfig(int id)
@ -79,19 +82,19 @@ namespace MTWireGuard.Services
} }
public async Task<MTInfoViewModel> GetInfo() public async Task<MTInfoViewModel> GetInfo()
{ {
var model = await APIHandler.GetInfo(); var model = await wrapper.GetInfo();
return mapper.Map<MTInfoViewModel>(model); return mapper.Map<MTInfoViewModel>(model);
} }
public async Task<MTIdentityViewModel> GetName() public async Task<MTIdentityViewModel> GetName()
{ {
var model = await APIHandler.GetName(); var model = await wrapper.GetName();
return mapper.Map<MTIdentityViewModel>(model); return mapper.Map<MTIdentityViewModel>(model);
} }
public async Task<bool> TryConnectAsync() public async Task<bool> TryConnectAsync()
{ {
try try
{ {
var model = await APIHandler.TryConnectAsync(); var model = await wrapper.TryConnectAsync();
if ((model.Error == 400 && model.Message == "Bad Request") || (model.Error == 401 && model.Message == "Unauthorized")) if ((model.Error == 400 && model.Message == "Bad Request") || (model.Error == 401 && model.Message == "Unauthorized"))
{ {
return true; return true;
@ -105,42 +108,42 @@ namespace MTWireGuard.Services
} }
public async Task<List<ActiveUserViewModel>> GetActiveSessions() public async Task<List<ActiveUserViewModel>> GetActiveSessions()
{ {
var model = await APIHandler.GetActiveSessions(); var model = await wrapper.GetActiveSessions();
return mapper.Map<List<ActiveUserViewModel>>(model); return mapper.Map<List<ActiveUserViewModel>>(model);
} }
public async Task<List<JobViewModel>> GetJobs() public async Task<List<JobViewModel>> GetJobs()
{ {
var model = await APIHandler.GetJobs(); var model = await wrapper.GetJobs();
return mapper.Map<List<JobViewModel>>(model); return mapper.Map<List<JobViewModel>>(model);
} }
public async Task<string> GetCurrentSessionID() public async Task<string> GetCurrentSessionID()
{ {
var activeSessions = await APIHandler.GetActiveSessions(); var activeSessions = await wrapper.GetActiveSessions();
var apiSession = activeSessions.Find(x => x.Via == "api"); var apiSession = activeSessions.Find(x => x.Via == "api");
var jobs = await APIHandler.GetJobs(); var jobs = await wrapper.GetJobs();
var currentJob = jobs.Find(x => x.Started == apiSession.When); var currentJob = jobs.Find(x => x.Started == apiSession.When);
return currentJob.Id; return currentJob.Id;
} }
public async Task<string> KillJob(string JobID) public async Task<string> KillJob(string JobID)
{ {
return await APIHandler.KillJob(JobID); return await wrapper.KillJob(JobID);
} }
public async Task<CreationResult> CreateServer(ServerCreateModel server) public async Task<CreationResult> CreateServer(ServerCreateModel server)
{ {
var srv = mapper.Map<WGServerCreateModel>(server); var srv = mapper.Map<MikrotikAPI.Models.WGServerCreateModel>(server);
var model = await APIHandler.CreateServer(srv); var model = await wrapper.CreateServer(srv);
return mapper.Map<CreationResult>(model); return mapper.Map<CreationResult>(model);
} }
public async Task<CreationResult> CreateUser(UserCreateModel peer) public async Task<CreationResult> CreateUser(UserCreateModel peer)
{ {
var user = mapper.Map<WGPeerCreateModel>(peer); var user = mapper.Map<MikrotikAPI.Models.WGPeerCreateModel>(peer);
var model = await APIHandler.CreateUser(user); var model = await wrapper.CreateUser(user);
if (model.Success) if (model.Success)
{ {
var item = model.Item as WGPeer; var item = model.Item as MikrotikAPI.Models.WGPeer;
await dbContext.Users.AddAsync(new() await dbContext.Users.AddAsync(new()
{ {
Id = Convert.ToInt32(item.Id[1..], 16), Id = Convert.ToInt32(item.Id[1..], 16),
@ -193,8 +196,8 @@ namespace MTWireGuard.Services
} }
if (mtUser.PublicKey != user.PublicKey) if (mtUser.PublicKey != user.PublicKey)
{ {
var fxUser = mapper.Map<WGPeerUpdateModel>(user); var fxUser = mapper.Map<MikrotikAPI.Models.WGPeerUpdateModel>(user);
var update = await APIHandler.UpdateUser(fxUser); var update = await wrapper.UpdateUser(fxUser);
result = mapper.Map<CreationResult>(update); result = mapper.Map<CreationResult>(update);
} }
return result; return result;
@ -202,8 +205,8 @@ namespace MTWireGuard.Services
public async Task<CreationResult> UpdateUser(UserUpdateModel user) public async Task<CreationResult> UpdateUser(UserUpdateModel user)
{ {
var mtPeer = mapper.Map<WGPeerUpdateModel>(user); var mtPeer = mapper.Map<MikrotikAPI.Models.WGPeerUpdateModel>(user);
var mtUpdate = await APIHandler.UpdateUser(mtPeer); var mtUpdate = await wrapper.UpdateUser(mtPeer);
if (mtUpdate.Success) if (mtUpdate.Success)
{ {
var exists = await dbContext.Users.FindAsync(user.Id); var exists = await dbContext.Users.FindAsync(user.Id);
@ -233,14 +236,14 @@ namespace MTWireGuard.Services
public async Task<CreationResult> UpdateServer(ServerUpdateModel server) public async Task<CreationResult> UpdateServer(ServerUpdateModel server)
{ {
var srv = mapper.Map<WGServerUpdateModel>(server); var srv = mapper.Map<MikrotikAPI.Models.WGServerUpdateModel>(server);
var mtUpdate = await APIHandler.UpdateServer(srv); var mtUpdate = await wrapper.UpdateServer(srv);
return mapper.Map<CreationResult>(mtUpdate); return mapper.Map<CreationResult>(mtUpdate);
} }
public async Task<CreationResult> EnableServer(int id) public async Task<CreationResult> EnableServer(int id)
{ {
var enable = await APIHandler.SetServerEnabled(new() var enable = await wrapper.SetServerEnabled(new()
{ {
ID = $"*{id:X}", ID = $"*{id:X}",
Disabled = false Disabled = false
@ -250,7 +253,7 @@ namespace MTWireGuard.Services
public async Task<CreationResult> DisableServer(int id) public async Task<CreationResult> DisableServer(int id)
{ {
var enable = await APIHandler.SetServerEnabled(new() var enable = await wrapper.SetServerEnabled(new()
{ {
ID = $"*{id:X}", ID = $"*{id:X}",
Disabled = true Disabled = true
@ -260,7 +263,7 @@ namespace MTWireGuard.Services
public async Task<CreationResult> EnableUser(int id) public async Task<CreationResult> EnableUser(int id)
{ {
var enable = await APIHandler.SetUserEnabled(new() var enable = await wrapper.SetUserEnabled(new()
{ {
ID = $"*{id:X}", ID = $"*{id:X}",
Disabled = false Disabled = false
@ -270,7 +273,7 @@ namespace MTWireGuard.Services
public async Task<CreationResult> DisableUser(int id) public async Task<CreationResult> DisableUser(int id)
{ {
var enable = await APIHandler.SetUserEnabled(new() var enable = await wrapper.SetUserEnabled(new()
{ {
ID = $"*{id:X}", ID = $"*{id:X}",
Disabled = true Disabled = true
@ -280,12 +283,12 @@ namespace MTWireGuard.Services
public async Task<CreationResult> DeleteServer(int id) public async Task<CreationResult> DeleteServer(int id)
{ {
var delete = await APIHandler.DeleteServer($"*{id:X}"); var delete = await wrapper.DeleteServer($"*{id:X}");
return mapper.Map<CreationResult>(delete); return mapper.Map<CreationResult>(delete);
} }
public async Task<CreationResult> DeleteUser(int id) public async Task<CreationResult> DeleteUser(int id)
{ {
var delete = await APIHandler.DeleteUser($"*{id:X}"); var delete = await wrapper.DeleteUser($"*{id:X}");
return mapper.Map<CreationResult>(delete); return mapper.Map<CreationResult>(delete);
} }

View file

@ -3,13 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.3.32819.101 VisualStudioVersion = 17.3.32819.101
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MTWireGuard", "MTWireGuard.csproj", "{F4826D62-8AB3-4565-A3F1-8FD5998DFA43}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MTWireGuard", "UI\MTWireGuard.csproj", "{F4826D62-8AB3-4565-A3F1-8FD5998DFA43}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{810BE84C-BB0A-4280-BBE9-E0A1B859BDED}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{810BE84C-BB0A-4280-BBE9-E0A1B859BDED}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig .editorconfig = .editorconfig
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MTWireGuard.Application", "Application\MTWireGuard.Application.csproj", "{D287FE39-390B-44B2-A62E-CE6030CA945B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MikrotikAPI", "MikrotikAPI\MikrotikAPI.csproj", "{357EE40B-AA30-482C-94CF-34854BE24D61}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -20,6 +24,14 @@ Global
{F4826D62-8AB3-4565-A3F1-8FD5998DFA43}.Debug|Any CPU.Build.0 = Debug|Any CPU {F4826D62-8AB3-4565-A3F1-8FD5998DFA43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F4826D62-8AB3-4565-A3F1-8FD5998DFA43}.Release|Any CPU.ActiveCfg = Release|Any CPU {F4826D62-8AB3-4565-A3F1-8FD5998DFA43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F4826D62-8AB3-4565-A3F1-8FD5998DFA43}.Release|Any CPU.Build.0 = Release|Any CPU {F4826D62-8AB3-4565-A3F1-8FD5998DFA43}.Release|Any CPU.Build.0 = Release|Any CPU
{D287FE39-390B-44B2-A62E-CE6030CA945B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D287FE39-390B-44B2-A62E-CE6030CA945B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D287FE39-390B-44B2-A62E-CE6030CA945B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D287FE39-390B-44B2-A62E-CE6030CA945B}.Release|Any CPU.Build.0 = Release|Any CPU
{357EE40B-AA30-482C-94CF-34854BE24D61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{357EE40B-AA30-482C-94CF-34854BE24D61}.Debug|Any CPU.Build.0 = Debug|Any CPU
{357EE40B-AA30-482C-94CF-34854BE24D61}.Release|Any CPU.ActiveCfg = Release|Any CPU
{357EE40B-AA30-482C-94CF-34854BE24D61}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -1,94 +1,98 @@
using Microsoft.AspNetCore.Hosting.Server; using MikrotikAPI.Models;
using MTWireGuard.Models;
using MTWireGuard.Models.Mikrotik;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Text; using System.Text;
namespace MTWireGuard namespace MikrotikAPI
{ {
public static class APIHandler public class APIWrapper
{ {
private static readonly string MT_IP = Environment.GetEnvironmentVariable("MT_IP"); private string MT_IP { get; set; }
private static readonly string MT_USER = Environment.GetEnvironmentVariable("MT_USER"); private string MT_USER { get; set; }
private static readonly string MT_PASS = Environment.GetEnvironmentVariable("MT_PASS"); private string MT_PASS { get; set; }
public static async Task<List<Log>> GetLogsAsync() public APIWrapper(string IP, string User, string Password)
{ {
string json = await SendGetRequestAsync("log"); MT_IP = IP;
return JsonConvert.DeserializeObject<List<Log>>(json); MT_USER = User;
MT_PASS = Password;
} }
public static async Task<List<WGServer>> GetServersAsync() public async Task<List<Log>> GetLogsAsync()
{ {
string json = await SendGetRequestAsync("interface/wireguard"); string json = await SendGetRequestAsync(Endpoints.Log);
return JsonConvert.DeserializeObject<List<WGServer>>(json); return json.ToModel<List<Log>>();
} }
public static async Task<WGServer> GetServer(string Name) public async Task<List<WGServer>> GetServersAsync()
{
string json = await SendGetRequestAsync(Endpoints.Wireguard);
return json.ToModel<List<WGServer>>();
}
public async Task<WGServer> GetServer(string Name)
{ {
var servers = await GetServersAsync(); var servers = await GetServersAsync();
return servers.Find(s => s.Name == Name); return servers.Find(s => s.Name == Name);
} }
public static async Task<List<ServerTraffic>> GetServersTraffic() public async Task<List<ServerTraffic>> GetServersTraffic()
{ {
var json = await SendPostRequestAsync("interface", "{\"stats\", {\".proplist\":\"name, type, rx-byte, tx-byte\"}}"); var json = await SendRequestBase(RequestMethod.GET, Endpoints.Interface, "{\"stats\", {\".proplist\":\"name, type, rx-byte, tx-byte\"}}");
return JsonConvert.DeserializeObject<List<ServerTraffic>>(json); return json.ToModel<List<ServerTraffic>>();
} }
public static async Task<List<WGPeer>> GetUsersAsync() public async Task<List<WGPeer>> GetUsersAsync()
{ {
using var db = new DBContext(); string json = await SendGetRequestAsync(Endpoints.WireguardPeers);
string json = await SendGetRequestAsync("interface/wireguard/peers"); return json.ToModel<List<WGPeer>>();
return JsonConvert.DeserializeObject<List<WGPeer>>(json);
} }
public static async Task<WGPeer> GetUser(string id) public async Task<WGPeer> GetUser(string id)
{ {
var users = await GetUsersAsync(); var users = await GetUsersAsync();
return users.Find(u => u.Id == id); return users.Find(u => u.Id == id);
} }
public static async Task<MTInfo> GetInfo() public async Task<MTInfo> GetInfo()
{ {
var json = await SendGetRequestAsync("system/resource"); var json = await SendGetRequestAsync(Endpoints.SystemResource);
return JsonConvert.DeserializeObject<MTInfo>(json); return json.ToModel<MTInfo>();
} }
public static async Task<MTIdentity> GetName() public async Task<MTIdentity> GetName()
{ {
var json = await SendGetRequestAsync("system/identity"); var json = await SendGetRequestAsync(Endpoints.SystemIdentity);
return JsonConvert.DeserializeObject<MTIdentity>(json); return json.ToModel<MTIdentity>();
} }
public static async Task<LoginStatus> TryConnectAsync() public async Task<LoginStatus> TryConnectAsync()
{ {
var connection = await SendGetRequestAsync("", true); var connection = await SendGetRequestAsync(Endpoints.Empty, true);
return JsonConvert.DeserializeObject<LoginStatus>(connection); return connection.ToModel<LoginStatus>();
} }
public static async Task<List<ActiveUser>> GetActiveSessions() public async Task<List<ActiveUser>> GetActiveSessions()
{ {
var json = await SendGetRequestAsync("user/active?name=" + MT_USER); var json = await SendGetRequestAsync($"{Endpoints.ActiveUsers}?name=" + MT_USER);
return JsonConvert.DeserializeObject<List<ActiveUser>>(json); return json.ToModel<List<ActiveUser>>();
} }
public static async Task<List<Job>> GetJobs() public async Task<List<Job>> GetJobs()
{ {
var json = await SendGetRequestAsync("system/script/job"); var json = await SendGetRequestAsync(Endpoints.Jobs);
return JsonConvert.DeserializeObject<List<Job>>(json); return json.ToModel<List<Job>>();
} }
public static async Task<string> KillJob(string JobID) public async Task<string> KillJob(string JobID)
{ {
return await SendDeleteRequestAsync("system/script/job/" + JobID); return await SendDeleteRequestAsync($"{Endpoints.Jobs}/" + JobID);
} }
public static async Task<CreationStatus> CreateServer(WGServerCreateModel server) public async Task<CreationStatus> CreateServer(WGServerCreateModel server)
{ {
var json = await SendPutRequestAsync("interface/wireguard", server); var json = await SendPutRequestAsync(Endpoints.Wireguard, server);
var obj = JObject.Parse(json); var obj = JObject.Parse(json);
bool success = false; bool success = false;
string code = string.Empty, message = string.Empty, detail = string.Empty; string code = string.Empty, message = string.Empty, detail = string.Empty;
@ -119,7 +123,7 @@ namespace MTWireGuard
}; };
} }
public static async Task<CreationStatus> CreateUser(WGPeerCreateModel user) public async Task<CreationStatus> CreateUser(WGPeerCreateModel user)
{ {
var jsonData = JObject.Parse(JsonConvert.SerializeObject(user, new JsonSerializerSettings var jsonData = JObject.Parse(JsonConvert.SerializeObject(user, new JsonSerializerSettings
{ {
@ -127,7 +131,7 @@ namespace MTWireGuard
DefaultValueHandling = DefaultValueHandling.Ignore DefaultValueHandling = DefaultValueHandling.Ignore
})); }));
var json = await SendPutRequestAsync("interface/wireguard/peers", jsonData); var json = await SendPutRequestAsync(Endpoints.WireguardPeers, jsonData);
var obj = JObject.Parse(json); var obj = JObject.Parse(json);
bool success = false; bool success = false;
string code = string.Empty, message = string.Empty, detail = string.Empty; string code = string.Empty, message = string.Empty, detail = string.Empty;
@ -161,14 +165,14 @@ namespace MTWireGuard
}; };
} }
public static async Task<CreationStatus> UpdateServer(WGServerUpdateModel server) public async Task<CreationStatus> UpdateServer(WGServerUpdateModel server)
{ {
var serverJson = JObject.Parse(JsonConvert.SerializeObject(server, new JsonSerializerSettings var serverJson = JObject.Parse(JsonConvert.SerializeObject(server, new JsonSerializerSettings
{ {
NullValueHandling = NullValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore DefaultValueHandling = DefaultValueHandling.Ignore
})); }));
var json = await SendPatchRequestAsync($"interface/wireguard/{server.Id}", serverJson); var json = await SendPatchRequestAsync($"{Endpoints.Wireguard}/{server.Id}", serverJson);
var obj = JObject.Parse(json); var obj = JObject.Parse(json);
bool success = false; bool success = false;
string code = string.Empty, message = string.Empty, detail = string.Empty; string code = string.Empty, message = string.Empty, detail = string.Empty;
@ -202,14 +206,14 @@ namespace MTWireGuard
}; };
} }
public static async Task<CreationStatus> UpdateUser(WGPeerUpdateModel user) public async Task<CreationStatus> UpdateUser(WGPeerUpdateModel user)
{ {
var userJson = JObject.Parse(JsonConvert.SerializeObject(user, new JsonSerializerSettings var userJson = JObject.Parse(JsonConvert.SerializeObject(user, new JsonSerializerSettings
{ {
NullValueHandling = NullValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore DefaultValueHandling = DefaultValueHandling.Ignore
})); }));
var json = await SendPatchRequestAsync($"interface/wireguard/peers/{user.Id}", userJson); var json = await SendPatchRequestAsync($"{Endpoints.WireguardPeers}/{user.Id}", userJson);
var obj = JObject.Parse(json); var obj = JObject.Parse(json);
bool success = false; bool success = false;
string code = string.Empty, message = string.Empty, detail = string.Empty; string code = string.Empty, message = string.Empty, detail = string.Empty;
@ -243,9 +247,9 @@ namespace MTWireGuard
}; };
} }
public static async Task<CreationStatus> SetServerEnabled(WGEnability enability) public async Task<CreationStatus> SetServerEnabled(WGEnability enability)
{ {
var json = await SendPatchRequestAsync($"interface/wireguard/{enability.ID}", new { disabled = enability.Disabled }); var json = await SendPatchRequestAsync($"{Endpoints.Wireguard}/{enability.ID}", new { disabled = enability.Disabled });
var obj = JObject.Parse(json); var obj = JObject.Parse(json);
bool success = false; bool success = false;
string code = string.Empty, message = string.Empty, detail = string.Empty; string code = string.Empty, message = string.Empty, detail = string.Empty;
@ -279,9 +283,9 @@ namespace MTWireGuard
}; };
} }
public static async Task<CreationStatus> SetUserEnabled(WGEnability enability) public async Task<CreationStatus> SetUserEnabled(WGEnability enability)
{ {
var json = await SendPatchRequestAsync($"interface/wireguard/peers/{enability.ID}", new { disabled = enability.Disabled }); var json = await SendPatchRequestAsync($"{Endpoints.WireguardPeers}/{enability.ID}", new { disabled = enability.Disabled });
var obj = JObject.Parse(json); var obj = JObject.Parse(json);
bool success = false; bool success = false;
string code = string.Empty, message = string.Empty, detail = string.Empty; string code = string.Empty, message = string.Empty, detail = string.Empty;
@ -315,9 +319,9 @@ namespace MTWireGuard
}; };
} }
public static async Task<CreationStatus> DeleteServer(string id) public async Task<CreationStatus> DeleteServer(string id)
{ {
var json = await SendDeleteRequestAsync("interface/wireguard/" + id); var json = await SendDeleteRequestAsync($"{Endpoints.Wireguard}/" + id);
if (string.IsNullOrWhiteSpace(json)) if (string.IsNullOrWhiteSpace(json))
{ {
return new() return new()
@ -335,9 +339,9 @@ namespace MTWireGuard
} }
} }
public static async Task<CreationStatus> DeleteUser(string id) public async Task<CreationStatus> DeleteUser(string id)
{ {
var json = await SendDeleteRequestAsync("interface/wireguard/peers/" + id); var json = await SendDeleteRequestAsync($"{Endpoints.WireguardPeers}/" + id);
if (string.IsNullOrWhiteSpace(json)) if (string.IsNullOrWhiteSpace(json))
{ {
return new() return new()
@ -355,93 +359,55 @@ namespace MTWireGuard
} }
} }
public static async Task<string> GetTrafficSpeed() public async Task<string> GetTrafficSpeed()
{ {
return await SendPostRequestAsync("interface/monitor-traffic", "{\"interface\":\"ether1\",\"duration\":\"3s\"}"); return await SendPostRequestAsync(Endpoints.MonitorTraffic, "{\"interface\":\"ether1\",\"duration\":\"3s\"}");
} }
private static async Task<string> SendGetRequestAsync(string URL, bool IsTest = false) private async Task<string> SendRequestBase(RequestMethod Method, string Endpoint, object Data = null, bool IsTest = false)
{ {
HttpClientHandler handler = new() HttpClientHandler handler = new()
{ {
ServerCertificateCustomValidationCallback = delegate { return true; } ServerCertificateCustomValidationCallback = (requestMessage, certificate, chain, policyErrors) => true
}; };
using HttpClient httpClient = new(handler); using HttpClient httpClient = new(handler);
using var request = new HttpRequestMessage(new HttpMethod("GET"), $"https://{MT_IP}/rest/{URL}"); using var request = new HttpRequestMessage(new HttpMethod(Method.ToString()), $"https://{MT_IP}/rest/{Endpoint}");
string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}")); string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}"));
if (!IsTest) request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}"); if (!IsTest) request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
if (Data != null)
HttpResponseMessage response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
private static async Task<string> SendPostRequestAsync(string URL, string Data)
{ {
HttpClientHandler handler = new() string content = (Data is string @string) ? @string : JsonConvert.SerializeObject(Data);
{ request.Content = new StringContent(content);
ServerCertificateCustomValidationCallback = (requestMessage, certificate, chain, policyErrors) => true
};
using HttpClient httpClient = new(handler);
using var request = new HttpRequestMessage(new HttpMethod("GET"), $"https://{MT_IP}/rest/{URL}");
string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
request.Content = new StringContent(Data);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
}
HttpResponseMessage response = await httpClient.SendAsync(request); HttpResponseMessage response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync(); return await response.Content.ReadAsStringAsync();
} }
private static async Task<string> SendDeleteRequestAsync(string URL) private async Task<string> SendGetRequestAsync(string URL, bool IsTest = false)
{ {
HttpClientHandler handler = new() return await SendRequestBase(RequestMethod.GET, URL, IsTest: IsTest);
{
ServerCertificateCustomValidationCallback = (requestMessage, certificate, chain, policyErrors) => true
};
using HttpClient httpClient = new(handler);
using var request = new HttpRequestMessage(new HttpMethod("DELETE"), $"https://{MT_IP}/rest/{URL}");
string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
HttpResponseMessage response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync();
} }
private static async Task<string> SendPutRequestAsync(string URL, object Data) private async Task<string> SendPostRequestAsync(string URL, string Data)
{ {
HttpClientHandler handler = new() return await SendRequestBase(RequestMethod.POST, URL, Data);
{
ServerCertificateCustomValidationCallback = (requestMessage, certificate, chain, policyErrors) => true
};
using HttpClient httpClient = new(handler);
using var request = new HttpRequestMessage(new HttpMethod("PUT"), $"https://{MT_IP}/rest/{URL}");
string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
request.Content = new StringContent(JsonConvert.SerializeObject(Data));
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
HttpResponseMessage response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync();
} }
private static async Task<string> SendPatchRequestAsync(string URL, object Data) private async Task<string> SendDeleteRequestAsync(string URL)
{ {
HttpClientHandler handler = new() return await SendRequestBase(RequestMethod.DELETE, URL);
}
private async Task<string> SendPutRequestAsync(string URL, object Data)
{ {
ServerCertificateCustomValidationCallback = (requestMessage, certificate, chain, policyErrors) => true return await SendRequestBase(RequestMethod.PUT, URL, Data);
}; }
using HttpClient httpClient = new(handler);
using var request = new HttpRequestMessage(new HttpMethod("PATCH"), $"https://{MT_IP}/rest/{URL}");
string base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{MT_USER}:{MT_PASS}"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
request.Content = new StringContent(JsonConvert.SerializeObject(Data)); private async Task<string> SendPatchRequestAsync(string URL, object Data)
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); {
return await SendRequestBase(RequestMethod.PATCH, URL, Data);
HttpResponseMessage response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync();
} }
} }
} }

25
MikrotikAPI/Endpoints.cs Normal file
View file

@ -0,0 +1,25 @@
namespace MikrotikAPI
{
public static class Endpoints
{
public const string Log = "log";
public const string Wireguard = "interface/wireguard";
public const string Interface = "interface";
public const string WireguardPeers = "interface/wireguard/peers";
public const string SystemResource = "system/resource";
public const string SystemIdentity = "system/identity";
public const string ActiveUsers = "user/active";
public const string Jobs = "system/script/job";
public const string MonitorTraffic = "interface/monitor-traffic";
public static string Empty => string.Empty;
}
public enum RequestMethod
{
GET,
POST,
PUT,
DELETE,
PATCH
}
}

13
MikrotikAPI/Extensions.cs Normal file
View file

@ -0,0 +1,13 @@
using Newtonsoft.Json;
namespace MikrotikAPI
{
public static class Extensions
{
public static T ToModel<T>(this string str)
{
if (string.IsNullOrWhiteSpace(str)) return default;
return JsonConvert.DeserializeObject<T>(str);
}
}
}

View file

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>

View file

@ -1,6 +1,6 @@
using Newtonsoft.Json; using Newtonsoft.Json;
namespace MTWireGuard.Models.Mikrotik namespace MikrotikAPI.Models
{ {
public class ActiveUser public class ActiveUser
{ {
@ -12,14 +12,4 @@ namespace MTWireGuard.Models.Mikrotik
public string Via { get; set; } public string Via { get; set; }
public string When { get; set; } public string When { get; set; }
} }
public class ActiveUserViewModel
{
public short Id { get; set; }
public string Group { get; set; }
public string Name { get; set; }
public bool Radius { get; set; }
public string Via { get; set; }
public string LoggedIn { get; set; }
}
} }

View file

@ -1,4 +1,4 @@
namespace MTWireGuard.Models namespace MikrotikAPI.Models
{ {
public class CreationStatus public class CreationStatus
{ {
@ -8,11 +8,4 @@
public string Message { get; set; } public string Message { get; set; }
public object Item { get; set; } public object Item { get; set; }
} }
public class CreationResult
{
public string Code { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
} }

View file

@ -0,0 +1,7 @@
namespace MikrotikAPI.Models
{
public class MTIdentity
{
public string Name { get; set; }
}
}

View file

@ -1,6 +1,6 @@
using Newtonsoft.Json; using Newtonsoft.Json;
namespace MTWireGuard.Models.Mikrotik namespace MikrotikAPI.Models
{ {
public class Job public class Job
{ {
@ -13,14 +13,4 @@ namespace MTWireGuard.Models.Mikrotik
public string Started { get; set; } public string Started { get; set; }
public string Type { get; set; } public string Type { get; set; }
} }
public class JobViewModel
{
public short Id { get; set; }
public short NextId { get; set; }
public string Owner { get; set; }
public List<string> Policies { get; set; }
public string Started { get; set; }
public string Type { get; set; }
}
} }

View file

@ -1,6 +1,6 @@
using Newtonsoft.Json; using Newtonsoft.Json;
namespace MTWireGuard.Models.Mikrotik namespace MikrotikAPI.Models
{ {
public class Log public class Log
{ {
@ -10,12 +10,4 @@ namespace MTWireGuard.Models.Mikrotik
public string Time { get; set; } public string Time { get; set; }
public string Topics { get; set; } public string Topics { get; set; }
} }
public class LogViewModel
{
public ulong Id { get; set; }
public string Message { get; set; }
public string Time { get; set; }
public List<string> Topics { get; set; }
}
} }

View file

@ -1,4 +1,4 @@
namespace MTWireGuard.Models namespace MikrotikAPI.Models
{ {
public class LoginStatus public class LoginStatus
{ {

View file

@ -0,0 +1,47 @@
using Newtonsoft.Json;
namespace MikrotikAPI.Models
{
public class MTInfo
{
[JsonProperty("architecture-name")]
public string ArchitectureName { get; set; }
[JsonProperty("board-name")]
public string BoardName { get; set; }
[JsonProperty("build-time")]
public string BuildTime { get; set; }
public string CPU { get; set; }
[JsonProperty("cpu-count")]
public string CPUCount { get; set; }
[JsonProperty("cpu-frequency")]
public string CPUFrequency { get; set; }
[JsonProperty("cpu-load")]
public string CPULoad { get; set; }
[JsonProperty("free-hdd-space")]
public string FreeHDDSpace { get; set; }
[JsonProperty("free-memory")]
public string FreeMemory { get; set; }
public string Platform { get; set; }
[JsonProperty("total-hdd-space")]
public string TotalHDDSpace { get; set; }
[JsonProperty("total-memory")]
public string TotalMemory { get; set; }
public string Uptime { get; set; }
public string Version { get; set; }
[JsonProperty("write-sect-since-reboot")]
public string WriteSectSinceReboot { get; set; }
[JsonProperty("write-sect-total")]
public string WriteSectTotal { get; set; }
}
}

View file

@ -0,0 +1,14 @@
using Newtonsoft.Json;
namespace MikrotikAPI.Models
{
public class ServerTraffic
{
public string Name { get; set; }
public string Type { get; set; }
[JsonProperty("tx-byte")]
public string TX { get; set; }
[JsonProperty("rx-byte")]
public string RX { get; set; }
}
}

View file

@ -1,6 +1,6 @@
using Newtonsoft.Json; using Newtonsoft.Json;
namespace MTWireGuard.Models namespace MikrotikAPI.Models
{ {
public class WGEnability public class WGEnability
{ {

View file

@ -1,8 +1,13 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MTWireGuard.Models.Mikrotik namespace MikrotikAPI.Models
{ {
public class WGPeer public class WGPeer
{ {
@ -30,34 +35,6 @@ namespace MTWireGuard.Models.Mikrotik
public string TX { get; set; } public string TX { get; set; }
} }
[PrimaryKey("Id")]
[Index("PrivateKey", IsUnique = true)]
[Index("PublicKey", IsUnique = true)]
public class WGPeerDBModel
{
public int Id { get; set; }
public string? Name { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
}
public class WGPeerViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string CurrentAddress { get; set; }
public bool IsEnabled { get; set; }
public string Interface { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
public string Download { get; set; }
public string Upload { get; set; }
public long DownloadBytes { get; set; }
public long UploadBytes { get; set; }
public bool IsDifferent { get; set; }
}
public class WGPeerCreateModel public class WGPeerCreateModel
{ {
[JsonProperty("allowed-address")] [JsonProperty("allowed-address")]
@ -97,40 +74,4 @@ namespace MTWireGuard.Models.Mikrotik
[JsonProperty("persistent-keepalive"), DefaultValue(0)] [JsonProperty("persistent-keepalive"), DefaultValue(0)]
public int PersistentKeepalive { get; set; } public int PersistentKeepalive { get; set; }
} }
public class UserCreateModel
{
public string Name { get; set; }
public string PrivateKey { get; set; }
public string AllowedAddress { get; set; }
public bool Disabled { get; set; }
public string Interface { get; set; }
public string EndpointAddress { get; set; }
public string EndpointPort { get; set; }
public string PublicKey { get; set; }
public string PresharedKey { get; set; }
public string PersistentKeepalive { get; set; }
}
public class UserSyncModel
{
public int Id { get; set; }
public string Name { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
}
public class UserUpdateModel
{
public int Id { get; set; }
public string Name { get; set; }
public string AllowedAddress { get; set; }
public string Interface { get; set; }
public string EndpointAddress { get; set; }
public ushort EndpointPort { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
public string PresharedKey { get; set; }
public int PersistentKeepalive { get; set; }
}
} }

View file

@ -1,7 +1,12 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MTWireGuard.Models.Mikrotik namespace MikrotikAPI.Models
{ {
public class WGServer public class WGServer
{ {
@ -23,36 +28,6 @@ namespace MTWireGuard.Models.Mikrotik
public bool Running { get; set; } public bool Running { get; set; }
} }
public class WGServerViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsEnabled { get; set; }
public ushort ListenPort { get; set; }
public ushort MTU { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
public bool Running { get; set; }
}
public class ServerCreateModel
{
public string Name { get; set; }
public bool Enabled { get; set; }
public string ListenPort { get; set; }
public string MTU { get; set; }
public string PrivateKey { get; set; }
}
public class ServerUpdateModel
{
public int Id { get; set; }
public string Name { get; set; }
public ushort ListenPort { get; set; }
public ushort MTU { get; set; }
public string PrivateKey { get; set; }
}
public class WGServerCreateModel public class WGServerCreateModel
{ {
[JsonProperty("name")] [JsonProperty("name")]

View file

@ -1,12 +0,0 @@
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace MTWireGuard.Models.Mikrotik
{
public class EtherIP
{
[JsonProperty(".id")]
public string Id { get; set; }
public string Address { get; set; }
}
}

View file

@ -1,12 +0,0 @@
namespace MTWireGuard.Models.Mikrotik
{
public class MTIdentity
{
public string Name { get; set; }
}
public class MTIdentityViewModel
{
public string Name { get; set; }
}
}

View file

@ -1,88 +0,0 @@
using Newtonsoft.Json;
namespace MTWireGuard.Models.Mikrotik
{
public class MTInfo
{
[JsonProperty("architecture-name")]
public string ArchitectureName { get; set; }
[JsonProperty("board-name")]
public string BoardName { get; set; }
[JsonProperty("build-time")]
public string BuildTime { get; set; }
public string CPU { get; set; }
[JsonProperty("cpu-count")]
public string CPUCount { get; set; }
[JsonProperty("cpu-frequency")]
public string CPUFrequency { get; set; }
[JsonProperty("cpu-load")]
public string CPULoad { get; set; }
[JsonProperty("free-hdd-space")]
public string FreeHDDSpace { get; set; }
[JsonProperty("free-memory")]
public string FreeMemory { get; set; }
public string Platform { get; set; }
[JsonProperty("total-hdd-space")]
public string TotalHDDSpace { get; set; }
[JsonProperty("total-memory")]
public string TotalMemory { get; set; }
public string Uptime { get; set; }
public string Version { get; set; }
[JsonProperty("write-sect-since-reboot")]
public string WriteSectSinceReboot { get; set; }
[JsonProperty("write-sect-total")]
public string WriteSectTotal { get; set; }
}
public class MTInfoViewModel
{
public string Architecture { get; set; }
public string BoardName { get; set; }
public string Platform { get; set; }
public string CPU { get; set; }
public byte CPUCount { get; set; }
public short CPUFrequency { get; set; }
public byte CPULoad { get; set; }
public string TotalHDD { get; set; }
public string UsedHDD { get; set; }
public string FreeHDD { get; set; }
public long TotalHDDBytes { get; set; }
public long UsedHDDBytes { get; set; }
public long FreeHDDBytes { get; set; }
public byte FreeHDDPercentage { get; set; }
public string TotalRAM { get; set; }
public string UsedRAM { get; set; }
public string FreeRAM { get; set; }
public long TotalRAMBytes { get; set; }
public long UsedRAMBytes { get; set; }
public long FreeRAMBytes { get; set; }
public byte FreeRAMPercentage { get; set; }
public string UPTime { get; set; }
public string Version { get; set; }
}
public class SidebarInfo
{
public int RAMUsedPercentage { get; set; }
public int CPUUsedPercentage { get; set; }
public int HDDUsedPercentage { get; set; }
public string RAMUsed { get; set; }
public string HDDUsed { get; set; }
public string TotalRAM { get; set; }
public string TotalHDD { get; set; }
public string RAMBgColor { get; set; }
public string CPUBgColor { get; set; }
public string HDDBgColor { get; set; }
}
}

View file

@ -1,24 +0,0 @@
using Newtonsoft.Json;
namespace MTWireGuard.Models.Mikrotik
{
public class ServerTraffic
{
public string Name { get; set; }
public string Type { get; set; }
[JsonProperty("tx-byte")]
public string TX { get; set; }
[JsonProperty("rx-byte")]
public string RX { get; set; }
}
public class ServerTrafficViewModel
{
public string Name { get; set; }
public string Type { get; set; }
public string Upload { get; set; }
public string Download { get; set; }
public long UploadBytes { get; set; }
public long DownloadBytes { get; set; }
}
}

View file

@ -1,34 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace MTWireGuard.Models.Responses
{
public class ToastResult : IActionResult
{
private class Toast
{
public string Title { get; set; }
public string Body { get; set; }
public string Background { get; set; }
}
private readonly Toast _result;
public ToastResult(string title, string body, string background)
{
_result = new()
{
Title = title,
Body = body,
Background = background
};
}
public async Task ExecuteResultAsync(ActionContext context)
{
var objectResult = new ObjectResult(_result);
await objectResult.ExecuteResultAsync(context);
}
}
}

View file

@ -11,18 +11,16 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.12" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.12" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="QRCoder" Version="1.4.2" />
<PackageReference Include="Razor.Templating.Core" Version="1.8.0" /> <PackageReference Include="Razor.Templating.Core" Version="1.8.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" /> <PackageReference Include="System.Drawing.Common" Version="7.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Application\MTWireGuard.Application.csproj" />
</ItemGroup>
</Project> </Project>

View file

@ -0,0 +1,58 @@
using AutoMapper;
using MTWireGuard.Application.Models;
using MTWireGuard.Application.Models.Mikrotik;
using MTWireGuard.Models.Requests;
using MTWireGuard.Models.Responses;
namespace MTWireGuard.Mapper
{
public class RequestProfile : Profile
{
public RequestProfile()
{
// Peer Request
CreateMap<CreateClientRequest, UserCreateModel>()
.ForMember(dest => dest.Disabled,
opt => opt.MapFrom(src => !src.Enabled))
.ForMember(dest => dest.EndpointAddress,
opt => opt.MapFrom(src => src.Endpoint))
.ForMember(dest => dest.PersistentKeepalive,
opt => opt.MapFrom(src => src.KeepAlive.ToString()));
CreateMap<SyncUserRequest, UserSyncModel>();
CreateMap<UpdateClientRequest, UserUpdateModel>()
.ForMember(dest => dest.EndpointAddress,
opt => opt.MapFrom(src => src.Endpoint))
.ForMember(dest => dest.PersistentKeepalive,
opt => opt.MapFrom(src => src.KeepAlive));
// Server Request
CreateMap<CreateServerRequest, ServerCreateModel>()
.ForMember(dest => dest.ListenPort,
opt => opt.MapFrom(src => src.Port));
CreateMap<UpdateServerRequest, ServerUpdateModel>()
.ForMember(dest => dest.ListenPort,
opt => opt.MapFrom(src => src.Port));
// Item Creation
CreateMap<MikrotikAPI.Models.CreationStatus, CreationResult>()
.ForMember(dest => dest.Code,
opt => opt.MapFrom(src => (src.Success) ? "200" : src.Code.ToString()))
.ForMember(dest => dest.Title,
opt => opt.MapFrom(src => (src.Success) ? "Done" : src.Message))
.ForMember(dest => dest.Description,
opt => opt.MapFrom(src => (src.Success) ? "Item created/updated successfully." : src.Detail));
// Toast Result
CreateMap<CreationResult, ToastMessage>()
.ForMember(dest => dest.Title,
opt => opt.MapFrom(src => src.Code == "200" ? src.Title : $"[{src.Code}] {src.Title}"))
.ForMember(dest => dest.Body,
opt => opt.MapFrom(src => src.Description))
.ForMember(dest => dest.Background,
opt => opt.MapFrom(src => src.Code == "200" ? "success" : "danger"));
}
}
}

View file

@ -1,9 +1,7 @@
using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Antiforgery;
using MTWireGuard.Pages; using MTWireGuard.Pages;
using MTWireGuard.Repositories;
using Newtonsoft.Json; using Newtonsoft.Json;
using Razor.Templating.Core; using Razor.Templating.Core;
using System.Globalization;
namespace MTWireGuard.Middlewares namespace MTWireGuard.Middlewares
{ {

View file

@ -1,5 +1,5 @@
using MTWireGuard.Pages; using MTWireGuard.Pages;
using MTWireGuard.Repositories; using MTWireGuard.Application.Repositories;
using Razor.Templating.Core; using Razor.Templating.Core;
using System.Globalization; using System.Globalization;

View file

@ -1,6 +1,4 @@
using MTWireGuard.Models.Mikrotik; using System.Net;
using System.Net;
using System.Reflection;
namespace MTWireGuard.Middlewares namespace MTWireGuard.Middlewares
{ {

View file

@ -1,5 +1,5 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Build.Framework; using System.ComponentModel.DataAnnotations;
namespace MTWireGuard.Models.Requests namespace MTWireGuard.Models.Requests
{ {

View file

@ -1,6 +1,4 @@
using System.Net; namespace MTWireGuard.Models.Requests
namespace MTWireGuard.Models.Requests
{ {
public class CreateClientRequest public class CreateClientRequest
{ {

View file

@ -1,6 +1,4 @@
using System.ComponentModel; namespace MTWireGuard.Models.Requests
namespace MTWireGuard.Models.Requests
{ {
public class CreateServerRequest public class CreateServerRequest
{ {

View file

@ -0,0 +1,9 @@
namespace MTWireGuard.Models.Responses
{
public class ToastMessage
{
public string Title { get; set; }
public string Body { get; set; }
public string Background { get; set; }
}
}

View file

@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace MTWireGuard.Models.Responses
{
public class ToastResult : IActionResult
{
private readonly ToastMessage _result;
public ToastResult(ToastMessage message)
{
_result = message;
}
public async Task ExecuteResultAsync(ActionContext context)
{
var objectResult = new ObjectResult(_result);
await objectResult.ExecuteResultAsync(context);
}
}
}

View file

@ -1,5 +1,5 @@
@page "{handler?}" @page "{handler?}"
@using MTWireGuard.Models.Mikrotik @using MTWireGuard.Application.Models.Mikrotik
@model MTWireGuard.Pages.ClientsModel @model MTWireGuard.Pages.ClientsModel
@{ @{
ViewData["Title"] = "Clients"; ViewData["Title"] = "Clients";

View file

@ -1,15 +1,11 @@
using AutoMapper; using AutoMapper;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using MTWireGuard.Models; using MTWireGuard.Application.Models;
using MTWireGuard.Models.Mikrotik; using MTWireGuard.Application.Models.Mikrotik;
using MTWireGuard.Application.Repositories;
using MTWireGuard.Models.Requests; using MTWireGuard.Models.Requests;
using MTWireGuard.Models.Responses; using MTWireGuard.Models.Responses;
using MTWireGuard.Repositories;
using Newtonsoft.Json;
using QRCoder;
using System.Drawing;
using System.Security.Cryptography.X509Certificates;
namespace MTWireGuard.Pages namespace MTWireGuard.Pages
{ {
@ -59,35 +55,47 @@ namespace MTWireGuard.Pages
{ {
var model = mapper.Map<UserCreateModel>(request); var model = mapper.Map<UserCreateModel>(request);
var make = await API.CreateUser(model); var make = await API.CreateUser(model);
var message = mapper.Map<ToastMessage>(make);
return new ToastResult(message);
/*
string status = make.Code == "200" ? "success" : "danger"; string status = make.Code == "200" ? "success" : "danger";
string title = make.Code == "200" ? make.Title : $"[{make.Code}] {make.Title}"; string title = make.Code == "200" ? make.Title : $"[{make.Code}] {make.Title}";
return new ToastResult(title, make.Description, status); return new ToastResult(title, make.Description, status);*/
} }
public async Task<IActionResult> OnPostDelete(DeleteRequest request) public async Task<IActionResult> OnPostDelete(DeleteRequest request)
{ {
var delete = await API.DeleteUser(request.Id); var delete = await API.DeleteUser(request.Id);
var message = mapper.Map<ToastMessage>(delete);
return new ToastResult(message);
/*
string status = delete.Code == "200" ? "success" : "danger"; string status = delete.Code == "200" ? "success" : "danger";
string title = delete.Code == "200" ? delete.Title : $"[{delete.Code}] {delete.Title}"; string title = delete.Code == "200" ? delete.Title : $"[{delete.Code}] {delete.Title}";
return new ToastResult(title, delete.Description, status); return new ToastResult(title, delete.Description, status);*/
} }
public async Task<IActionResult> OnPostUpdate(UpdateClientRequest request) public async Task<IActionResult> OnPostUpdate(UpdateClientRequest request)
{ {
var model = mapper.Map<UserUpdateModel>(request); var model = mapper.Map<UserUpdateModel>(request);
var update = await API.UpdateUser(model); var update = await API.UpdateUser(model);
var message = mapper.Map<ToastMessage>(update);
return new ToastResult(message);
/*
string status = update.Code == "200" ? "success" : "danger"; string status = update.Code == "200" ? "success" : "danger";
string title = update.Code == "200" ? update.Title : $"[{update.Code}] {update.Title}"; string title = update.Code == "200" ? update.Title : $"[{update.Code}] {update.Title}";
return new ToastResult(title, update.Description, status); return new ToastResult(title, update.Description, status);*/
} }
public async Task<IActionResult> OnPostSyncAsync(SyncUserRequest request) public async Task<IActionResult> OnPostSyncAsync(SyncUserRequest request)
{ {
var model = mapper.Map<UserSyncModel>(request); var model = mapper.Map<UserSyncModel>(request);
var update = await API.SyncUser(model); var update = await API.SyncUser(model);
var message = mapper.Map<ToastMessage>(update);
return new ToastResult(message);
/*
string status = update.Code == "200" ? "success" : "danger"; string status = update.Code == "200" ? "success" : "danger";
string title = update.Code == "200" ? update.Title : $"[{update.Code}] {update.Title}"; string title = update.Code == "200" ? update.Title : $"[{update.Code}] {update.Title}";
return new ToastResult(title, update.Description, status); return new ToastResult(title, update.Description, status);*/
} }
public async Task<IActionResult> OnGetEnableAsync(ChangeStateRequest request) public async Task<IActionResult> OnGetEnableAsync(ChangeStateRequest request)
@ -97,9 +105,12 @@ namespace MTWireGuard.Pages
result = await API.EnableUser(request.Id); result = await API.EnableUser(request.Id);
else else
result = await API.DisableUser(request.Id); result = await API.DisableUser(request.Id);
var message = mapper.Map<ToastMessage>(result);
return new ToastResult(message);
/*
string status = result.Code == "200" ? "success" : "danger"; string status = result.Code == "200" ? "success" : "danger";
string title = result.Code == "200" ? result.Title : $"[{result.Code}] {result.Title}"; string title = result.Code == "200" ? result.Title : $"[{result.Code}] {result.Title}";
return new ToastResult(title, result.Description, status); return new ToastResult(title, result.Description, status);*/
} }
} }
} }

View file

@ -1,7 +1,8 @@
@using MTWireGuard.Models.Requests @using MTWireGuard.Application.Models.Mikrotik
@using MTWireGuard.Models.Requests
@model CreateClientRequest @model CreateClientRequest
@{ @{
List<Models.Mikrotik.WGServerViewModel> Servers = ViewData["Servers"] as List<Models.Mikrotik.WGServerViewModel>; List<WGServerViewModel> Servers = ViewData["Servers"] as List<WGServerViewModel>;
} }
<div class="card mb-4"> <div class="card mb-4">
<div class="card-header">Quick add peer</div> <div class="card-header">Quick add peer</div>

View file

@ -1,4 +1,5 @@
@{ @using MTWireGuard.Application.Models.Mikrotik
@{
int LogCount = Logs.Count <= 20 ? Logs.Count : 20; int LogCount = Logs.Count <= 20 ? Logs.Count : 20;
var LastLogs = Logs.TakeLast(LogCount).ToList(); var LastLogs = Logs.TakeLast(LogCount).ToList();
} }
@ -50,5 +51,5 @@
@code { @code {
[Parameter] [Parameter]
public List<Models.Mikrotik.LogViewModel> Logs { get; set; } public List<LogViewModel> Logs { get; set; }
} }

View file

@ -1,7 +1,8 @@
@using MTWireGuard.Models.Requests @using MTWireGuard.Application.Models.Mikrotik
@using MTWireGuard.Models.Requests
@model UpdateClientRequest @model UpdateClientRequest
@{ @{
List<Models.Mikrotik.WGServerViewModel> Servers = ViewData["Servers"] as List<Models.Mikrotik.WGServerViewModel>; List<WGServerViewModel> Servers = ViewData["Servers"] as List<WGServerViewModel>;
} }
<div class="modal fade" id="EditModal" tabindex="-1" aria-labelledby="EditModalLabel" aria-hidden="true"> <div class="modal fade" id="EditModal" tabindex="-1" aria-labelledby="EditModalLabel" aria-hidden="true">

View file

@ -1,5 +1,5 @@
@page @page
@using MTWireGuard.Models.Mikrotik @using MTWireGuard.Application.Models.Mikrotik
@model IndexModel @model IndexModel
@{ @{
ViewData["Title"] = "Dashboard"; ViewData["Title"] = "Dashboard";

View file

@ -1,7 +1,8 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using MTWireGuard.Repositories; using MTWireGuard.Application;
using MTWireGuard.Application.Repositories;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Net; using System.Net;
using System.Text; using System.Text;

View file

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using MTWireGuard.Repositories; using MTWireGuard.Application.Repositories;
namespace MTWireGuard.Pages namespace MTWireGuard.Pages
{ {

View file

@ -1,5 +1,5 @@
@page @page
@using MTWireGuard.Models.Mikrotik @using MTWireGuard.Application.Models.Mikrotik
@model MTWireGuard.Pages.LogsModel @model MTWireGuard.Pages.LogsModel
@{ @{
ViewData["Title"] = "Event Logs"; ViewData["Title"] = "Event Logs";

View file

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using MTWireGuard.Repositories; using MTWireGuard.Application.Repositories;
namespace MTWireGuard.Pages namespace MTWireGuard.Pages
{ {

View file

@ -1,5 +1,5 @@
@page "{handler?}" @page "{handler?}"
@using MTWireGuard.Models.Mikrotik @using MTWireGuard.Application.Models.Mikrotik
@model MTWireGuard.Pages.ServersModel @model MTWireGuard.Pages.ServersModel
@{ @{
ViewData["Title"] = "Servers"; ViewData["Title"] = "Servers";

View file

@ -1,11 +1,11 @@
using AutoMapper; using AutoMapper;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using MTWireGuard.Models; using MTWireGuard.Application.Models;
using MTWireGuard.Models.Mikrotik; using MTWireGuard.Application.Models.Mikrotik;
using MTWireGuard.Models.Requests; using MTWireGuard.Models.Requests;
using MTWireGuard.Models.Responses; using MTWireGuard.Models.Responses;
using MTWireGuard.Repositories; using MTWireGuard.Application.Repositories;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace MTWireGuard.Pages namespace MTWireGuard.Pages
@ -36,26 +36,35 @@ namespace MTWireGuard.Pages
{ {
var model = mapper.Map<ServerCreateModel>(request); var model = mapper.Map<ServerCreateModel>(request);
var make = await API.CreateServer(model); var make = await API.CreateServer(model);
var message = mapper.Map<ToastMessage>(make);
return new ToastResult(message);
/*
string status = make.Code == "200" ? "success" : "danger"; string status = make.Code == "200" ? "success" : "danger";
string title = make.Code == "200" ? make.Title : $"[{make.Code}] {make.Title}"; string title = make.Code == "200" ? make.Title : $"[{make.Code}] {make.Title}";
return new ToastResult(title, make.Description, status); return new ToastResult(title, make.Description, status);*/
} }
public async Task<IActionResult> OnPostDelete(DeleteRequest request) public async Task<IActionResult> OnPostDelete(DeleteRequest request)
{ {
var delete = await API.DeleteServer(request.Id); var delete = await API.DeleteServer(request.Id);
var message = mapper.Map<ToastMessage>(delete);
return new ToastResult(message);
/*
string status = delete.Code == "200" ? "success" : "danger"; string status = delete.Code == "200" ? "success" : "danger";
string title = delete.Code == "200" ? delete.Title : $"[{delete.Code}] {delete.Title}"; string title = delete.Code == "200" ? delete.Title : $"[{delete.Code}] {delete.Title}";
return new ToastResult(title, delete.Description, status); return new ToastResult(title, delete.Description, status);*/
} }
public async Task<IActionResult> OnPostUpdate(UpdateServerRequest request) public async Task<IActionResult> OnPostUpdate(UpdateServerRequest request)
{ {
var model = mapper.Map<ServerUpdateModel>(request); var model = mapper.Map<ServerUpdateModel>(request);
var update = await API.UpdateServer(model); var update = await API.UpdateServer(model);
var message = mapper.Map<ToastMessage>(update);
return new ToastResult(message);
/*
string status = update.Code == "200" ? "success" : "danger"; string status = update.Code == "200" ? "success" : "danger";
string title = update.Code == "200" ? update.Title : $"[{update.Code}] {update.Title}"; string title = update.Code == "200" ? update.Title : $"[{update.Code}] {update.Title}";
return new ToastResult(title, update.Description, status); return new ToastResult(title, update.Description, status);*/
} }
public async Task<IActionResult> OnGetEnableAsync(ChangeStateRequest request) public async Task<IActionResult> OnGetEnableAsync(ChangeStateRequest request)
@ -65,9 +74,12 @@ namespace MTWireGuard.Pages
result = await API.EnableServer(request.Id); result = await API.EnableServer(request.Id);
else else
result = await API.DisableServer(request.Id); result = await API.DisableServer(request.Id);
var message = mapper.Map<ToastMessage>(result);
return new ToastResult(message);
/*
string status = result.Code == "200" ? "success" : "danger"; string status = result.Code == "200" ? "success" : "danger";
string title = result.Code == "200" ? result.Title : $"[{result.Code}] {result.Title}"; string title = result.Code == "200" ? result.Title : $"[{result.Code}] {result.Title}";
return new ToastResult(title, result.Description, status); return new ToastResult(title, result.Description, status);*/
} }
} }
} }

View file

@ -1,5 +1,5 @@
@page "{handler?}" @page "{handler?}"
@using MTWireGuard.Models.Mikrotik @using MTWireGuard.Application.Models.Mikrotik
@model SettingsModel @model SettingsModel
@{ @{
ViewData["Title"] = "System Settings"; ViewData["Title"] = "System Settings";

View file

@ -1,8 +1,8 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using MTWireGuard.Models.Mikrotik; using MTWireGuard.Application.Models;
using MTWireGuard.Repositories; using MTWireGuard.Application.Repositories;
namespace MTWireGuard.Pages namespace MTWireGuard.Pages
{ {

View file

@ -1,4 +1,4 @@
@using MTWireGuard.Models.Mikrotik @using MTWireGuard.Application.Models.Mikrotik
@model List<WGPeerViewModel> @model List<WGPeerViewModel>
@foreach (var user in Model) @foreach (var user in Model)

View file

@ -1,4 +1,4 @@
@using MTWireGuard.Repositories @using MTWireGuard.Application.Repositories
@inject IMikrotikRepository API; @inject IMikrotikRepository API;
@{ @{
var logs = await API.GetLogsAsync(); var logs = await API.GetLogsAsync();

View file

@ -1,4 +1,4 @@
@using MTWireGuard.Models.Mikrotik @using MTWireGuard.Application.Models.Mikrotik
@model (List<WGServerViewModel>, List<ServerTrafficViewModel>) @model (List<WGServerViewModel>, List<ServerTrafficViewModel>)
@{ @{
var servers = Model.Item1; var servers = Model.Item1;

View file

@ -1,16 +1,9 @@
using AutoMapper;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using MTWireGuard;
using MTWireGuard.Mapper;
using MTWireGuard.Middlewares; using MTWireGuard.Middlewares;
using MTWireGuard.Repositories; using MTWireGuard.Application;
using MTWireGuard.Services; using MTWireGuard.Mapper;
using System.Diagnostics;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
using DBContext context = new();
// Add services to the container. // Add services to the container.
builder.Services.AddRazorPages().AddRazorPagesOptions(o => builder.Services.AddRazorPages().AddRazorPagesOptions(o =>
@ -27,22 +20,9 @@ builder.Services.AddAntiforgery(o =>
o.Cookie.Name = "XSRF-Validation"; o.Cookie.Name = "XSRF-Validation";
}); });
// Auto Mapper Configurations builder.Services.AddAutoMapper(typeof(RequestProfile));
var mapperConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new MappingProfile());
mc.AddProfile(new PeerMapping(context));
mc.AddProfile(new ServerMapping());
});
IMapper mapper = mapperConfig.CreateMapper(); builder.Services.AddApplicationServices();
builder.Services.AddSingleton(mapper);
builder.Services.AddSingleton(context);
builder.Services.AddSingleton<IMikrotikRepository, MTAPI>();
//builder.Services.AddScoped<AntiForgeryMiddleware>();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options => builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{ {
@ -75,10 +55,12 @@ if (!app.Environment.IsDevelopment())
app.UseHsts(); app.UseHsts();
} }
context.Database.EnsureCreated();
app.UseHttpsRedirection(); app.UseHttpsRedirection();
// Ensure Database Exists
var serviceScope = app.Services.CreateScope().ServiceProvider;
serviceScope.GetService<DBContext>().Database.EnsureCreated();
if (!app.Environment.IsDevelopment()) if (!app.Environment.IsDevelopment())
app.UseStaticFiles(); app.UseStaticFiles();
else else

Some files were not shown because too many files have changed in this diff Show more