1
0

380 lines
11 KiB
C#

using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Threading;
using DynamicData;
using Flawless.Client.Models;
using Flawless.Client.Remote;
using Flawless.Client.Service;
using Flawless.Client.ViewModels.ModalBox;
using Flawless.Client.Views.ModalBox;
using ReactiveUI;
using ReactiveUI.SourceGenerators;
using Refit;
using Ursa.Controls;
namespace Flawless.Client.ViewModels;
public record Log(DateTime Time, Microsoft.Extensions.Logging.LogLevel Level, string Message)
{
public static Log From(LogEntryResponse response) => new(
response.Timestamp.LocalDateTime,
Enum.Parse<Microsoft.Extensions.Logging.LogLevel>(response.Level),
response.Message);
}
public partial class SettingViewModel : RoutableViewModelBase
{
public ObservableCollection<UserModel> Users { get; } = new();
public ObservableCollection<Log> Logs { get; } = new();
public AppSettingModel SettingModel => SettingService.C.AppSetting;
[Reactive] private UserModel _loginUser;
[Reactive] private string _nickname;
[Reactive] private string _email;
[Reactive] private string _phoneNumber;
[Reactive] private UserModel.SexType _gender;
[Reactive] private string _bio;
[Reactive] private DateTime?
_logSearchFrom = null,
_logSearchTo = null;
[Reactive] private int _page = 1;
[Reactive] private int _pageSize = 50;
[Reactive] private Microsoft.Extensions.Logging.LogLevel _loglevel = Microsoft.Extensions.Logging.LogLevel.Information;
[Reactive] private string _serverBlacklist, _serverWhitelist;
public SettingViewModel(IScreen hostScreen) : base(hostScreen)
{
LoadClientSettings();
}
private async Task LoadServerData()
{
try
{
var sb = new StringBuilder();
ServerBlacklist = sb.AppendJoin(",\n", await Api.C.Gateway.IpWhitelistGet()).ToString();
ServerBlacklist = sb.Clear().AppendJoin(",\n", await Api.C.Gateway.IpBlacklistGet()).ToString();
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
try
{
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
private async Task LoadClientSettings()
{
LoginUser = (await UserService.C.GetOrDownloadUserInfoAsync(Api.C.Username.Value!))!;
Nickname = LoginUser.Nickname;
Email = LoginUser.Email;
PhoneNumber = LoginUser.PhoneNumber;
Gender = LoginUser.Sex;
Bio = LoginUser.Bio;
if (LoginUser.IsAdmin) await LoadServerData();
}
[ReactiveCommand]
private async Task SaveAccountChangesAsync()
{
try
{
await Api.C.Gateway.UpdateInfo(new UserInfoModifyResponse
{
NickName = this.Nickname == LoginUser.Nickname ? null! : this.Nickname,
Gender = this.Gender == LoginUser.Sex ? null : (UserSex) this.Gender,
Bio = this.Bio == LoginUser.Bio ? null! : this.Bio
});
if (Email != LoginUser.Email)
await Api.C.Gateway.UpdateEmail(new UserContactModifyResponse
{ Email = Email, });
if (PhoneNumber != LoginUser.PhoneNumber)
await Api.C.Gateway.UpdatePhone(new UserContactModifyResponse
{ Phone = PhoneNumber, });
UIHelper.NotifySuccess("Saved");
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
[ReactiveCommand]
private async Task ChangePasswordAsync()
{
var result = new PasswordChangeDialogViewModel();
var opt = UIHelper.DefaultOverlayDialogOptionsYesNo();
while (true)
{
var r = await OverlayDialog.ShowModal<PasswordChangeDialogView, PasswordChangeDialogViewModel>(result, AppDefaultValues.HostId, opt);
if (r == DialogResult.No) return;
if (result.Validate()) break;
UIHelper.NotifyError("Please check your input");
}
try
{
await Api.C.Gateway.ResetPassword(new ResetPasswordRequest()
{
Identity = LoginUser.Username,
NewPassword = result.NewPassword,
OldPassword = result.OldPassword
});
UIHelper.NotifySuccess("Password create successfully");
}
catch (ApiException ex)
{
UIHelper.NotifyError(ex);
}
}
[ReactiveCommand]
private async Task DeleteSelfAccountAsync()
{
if (await UIHelper.SimpleAskAsync("This operation can not undo. Do you sure that?") == DialogResult.Yes)
{
try
{
await Api.C.Gateway.Delete(Api.C.Username.Value!);
Process.GetCurrentProcess().Kill();
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
}
[ReactiveCommand]
private async Task SaveClientPreferenceAsync()
{
try
{
await SettingService.C.WriteToDiskAsync();
UIHelper.NotifySuccess("Saved Success!");
}
catch (Exception e)
{
UIHelper.NotifyError(e);
}
}
[ReactiveCommand]
private async Task SaveServerPreferenceAsync()
{
try
{
await Api.C.Gateway.IpWhitelistPost(ServerWhitelist.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries));
await Api.C.Gateway.IpBlacklistPost(ServerBlacklist.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries));
UIHelper.NotifySuccess("Saved Success!");
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
[ReactiveCommand]
private async Task ResetClientPreferenceAsync()
{
if (await UIHelper.SimpleAskAsync("Do you sure reset settings to default?") == DialogResult.Yes)
{
await SettingService.C.ResetAsync();
}
}
[ReactiveCommand]
private async Task ResetServerPreferenceAsync()
{
if (await UIHelper.SimpleAskAsync("Do you sure reset settings to default?") == DialogResult.Yes)
{
try
{
ServerBlacklist = ServerWhitelist = string.Empty;
await Api.C.Gateway.IpBlacklistPost([]);
await Api.C.Gateway.IpWhitelistPost([]);
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
}
[ReactiveCommand]
private async Task CreateUserAsync()
{
var result = new UserCreateDialogViewModel();
result.Password = GenerateRandomPassword();
var opt = UIHelper.DefaultOverlayDialogOptionsYesNo();
while (true)
{
var r = await OverlayDialog.ShowModal<UserCreateDialogView, UserCreateDialogViewModel>(result, AppDefaultValues.HostId, opt);
if (r == DialogResult.No) return;
if (result.Validate()) break;
UIHelper.NotifyError("Please check your input");
}
try
{
await Api.C.Gateway.Register(new RegisterRequest()
{
Username = result.Username,
Password = result.Password,
Email = result.Email
});
Users.Add(UserService.C.GetUserInfoAsync(result.Username)!);
UIHelper.NotifySuccess($"User {result.Username} create successfully");
}
catch (ApiException ex)
{
UIHelper.NotifyError(ex);
}
}
[ReactiveCommand]
private async Task DeleteUserAsync(string username)
{
if (await UIHelper.SimpleAskAsync($"Do you sure that wanted to delete user '{username}' permanently?") == DialogResult.Yes)
{
try
{
await Api.C.Gateway.Delete(username);
Users.Remove(Users.First(u => u.Username == username));
UIHelper.NotifySuccess("User deleted");
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
}
[ReactiveCommand]
private async Task ForceUpdateUserPasswordAsync(string username)
{
var newPassword = GenerateRandomPassword();
try
{
await Api.C.Gateway.RenewPassword(new ResetPasswordRequest
{
Identity = username,
NewPassword = newPassword
});
await UIHelper.SimpleAlert($"Password has been reset to {newPassword}");
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
[ReactiveCommand]
private async Task ActivateUserAsync(string username)
{
await UpdateUserActivateAsync(username, true);
}
[ReactiveCommand]
private async Task InactivateUserAsync(string username)
{
await UpdateUserActivateAsync(username, false);
}
[ReactiveCommand]
private async Task PromoteUserAsync(string username)
{
await UpdateUserSuperAsync(username, true);
}
[ReactiveCommand]
private async Task DemoteUserAsync(string username)
{
await UpdateUserSuperAsync(username, false);
}
[ReactiveCommand]
private async Task DownloadServerLogAsync()
{
try
{
var logs = await Api.C.Gateway.Logs(
LogSearchFrom, LogSearchTo, (LogLevel?)Loglevel, Page, PageSize);
Logs.AddRange(logs.Select(Log.From));
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
private async Task UpdateUserActivateAsync(string username, bool active)
{
try
{
if (active) await Api.C.Gateway.Enable(username);
else await Api.C.Gateway.Disable(username);
UIHelper.NotifySuccess($"{username} has already {(active ? "enabled" : "disabled")}.");
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
private async Task UpdateUserSuperAsync(string username, bool active)
{
try
{
await Api.C.Gateway.SuperuserPost(username, active);
Users.First(x => x.Username == username).IsAdmin = active;
UIHelper.NotifySuccess($"{username} has already {(active ? "enabled" : "disabled")}.");
}
catch (Exception ex)
{
UIHelper.NotifyError(ex);
}
}
private static string GenerateRandomPassword(int length = 12)
{
const string validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*";
var random = new Random();
return new string(Enumerable.Repeat(validChars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
}