Added user change status try catch, implement logout. password change admin

This commit is contained in:
Marcel Baumgartner
2023-04-20 12:29:01 +02:00
parent e79ec35bdc
commit 1b1bc80866
13 changed files with 116 additions and 43 deletions

View File

@@ -1,5 +1,4 @@
using System.ComponentModel.DataAnnotations;
using Moonlight.App.Models.Misc;
using Moonlight.App.Models.Misc;
namespace Moonlight.App.Database.Entities;
@@ -34,7 +33,7 @@ public class User
// Security
public bool TotpEnabled { get; set; } = false;
public string TotpSecret { get; set; } = "";
public DateTime TokenValidTime { get; set; } = DateTime.Now;
public DateTime TokenValidTime { get; set; } = DateTime.UtcNow;
// Discord
public ulong DiscordId { get; set; }

View File

@@ -18,17 +18,19 @@ public class OAuth2Controller : Controller
private readonly DiscordOAuth2Service DiscordOAuth2Service;
private readonly UserRepository UserRepository;
private readonly UserService UserService;
private readonly DateTimeService DateTimeService;
public OAuth2Controller(
GoogleOAuth2Service googleOAuth2Service,
UserRepository userRepository,
UserService userService,
DiscordOAuth2Service discordOAuth2Service)
DiscordOAuth2Service discordOAuth2Service, DateTimeService dateTimeService)
{
GoogleOAuth2Service = googleOAuth2Service;
UserRepository = userRepository;
UserService = userService;
DiscordOAuth2Service = discordOAuth2Service;
DateTimeService = dateTimeService;
}
[HttpGet("google")]
@@ -63,7 +65,7 @@ public class OAuth2Controller : Controller
Response.Cookies.Append("token", token, new ()
{
Expires = new DateTimeOffset(DateTime.UtcNow.AddDays(10))
Expires = new DateTimeOffset(DateTimeService.GetCurrent().AddDays(10))
});
return Redirect("/");
@@ -121,7 +123,7 @@ public class OAuth2Controller : Controller
Response.Cookies.Append("token", token, new ()
{
Expires = new DateTimeOffset(DateTime.UtcNow.AddDays(10))
Expires = new DateTimeOffset(DateTimeService.GetCurrent().AddDays(10))
});
return Redirect("/");

View File

@@ -1,16 +1,19 @@
using Microsoft.EntityFrameworkCore;
using Moonlight.App.Database;
using Moonlight.App.Database.Entities;
using Moonlight.App.Services;
namespace Moonlight.App.Repositories;
public class StatisticsRepository : IDisposable
{
private readonly DataContext DataContext;
private readonly DateTimeService DateTimeService;
public StatisticsRepository(DataContext dataContext)
public StatisticsRepository(DataContext dataContext, DateTimeService dateTimeService)
{
DataContext = dataContext;
DateTimeService = dateTimeService;
}
public DbSet<StatisticsData> Get()
@@ -27,7 +30,7 @@ public class StatisticsRepository : IDisposable
public StatisticsData Add(string chart, double value)
{
return Add(new StatisticsData() {Chart = chart, Value = value, Date = DateTime.Now});
return Add(new StatisticsData() {Chart = chart, Value = value, Date = DateTimeService.GetCurrent()});
}
public void Dispose()

View File

@@ -24,20 +24,23 @@ public class CleanupService
private readonly ConfigService ConfigService;
private readonly MessageService MessageService;
private readonly DateTimeService DateTimeService;
private readonly IServiceScopeFactory ServiceScopeFactory;
private readonly PeriodicTimer Timer;
public CleanupService(
ConfigService configService,
IServiceScopeFactory serviceScopeFactory,
MessageService messageService)
MessageService messageService,
DateTimeService dateTimeService)
{
ServiceScopeFactory = serviceScopeFactory;
MessageService = messageService;
DateTimeService = dateTimeService;
ConfigService = configService;
StartedAt = DateTime.Now;
CompletedAt = DateTime.Now;
StartedAt = DateTimeService.GetCurrent();
CompletedAt = DateTimeService.GetCurrent();
IsRunning = false;
var config = ConfigService.GetSection("Moonlight").GetSection("Cleanup");

View File

@@ -0,0 +1,31 @@
using Moonlight.App.Helpers;
namespace Moonlight.App.Services;
public class DateTimeService
{
public long GetCurrentUnix()
{
return new DateTimeOffset(GetCurrent()).ToUnixTimeMilliseconds();
}
public long GetCurrentUnixSeconds()
{
return new DateTimeOffset(GetCurrent()).ToUnixTimeSeconds();
}
public DateTime GetCurrent()
{
return DateTime.UtcNow;
}
public string GetDate()
{
return Formatter.FormatDateOnly(GetCurrent());
}
public string GetDateTime()
{
return Formatter.FormatDate(GetCurrent());
}
}

View File

@@ -31,6 +31,7 @@ public class ServerService
private readonly AuditLogService AuditLogService;
private readonly ErrorLogService ErrorLogService;
private readonly NodeService NodeService;
private readonly DateTimeService DateTimeService;
public ServerService(
ServerRepository serverRepository,
@@ -46,7 +47,8 @@ public class ServerService
AuditLogService auditLogService,
ErrorLogService errorLogService,
NodeService nodeService,
NodeAllocationRepository nodeAllocationRepository)
NodeAllocationRepository nodeAllocationRepository,
DateTimeService dateTimeService)
{
ServerRepository = serverRepository;
WingsApiHelper = wingsApiHelper;
@@ -62,6 +64,7 @@ public class ServerService
ErrorLogService = errorLogService;
NodeService = nodeService;
NodeAllocationRepository = nodeAllocationRepository;
DateTimeService = dateTimeService;
}
private Server EnsureNodeData(Server s)
@@ -115,9 +118,9 @@ public class ServerService
var backup = new ServerBackup()
{
Name = $"Created at {DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}",
Name = $"Created at {DateTimeService.GetCurrent().ToShortDateString()} {DateTimeService.GetCurrent().ToShortTimeString()}",
Uuid = Guid.NewGuid(),
CreatedAt = DateTime.Now,
CreatedAt = DateTimeService.GetCurrent(),
Created = false
};

View File

@@ -4,6 +4,7 @@ using JWT.Builder;
using JWT.Exceptions;
using Logging.Net;
using Moonlight.App.Database.Entities;
using Moonlight.App.Helpers;
using Moonlight.App.Models.Misc;
using Moonlight.App.Repositories;
using Moonlight.App.Services.LogServices;
@@ -123,9 +124,9 @@ public class IdentityService
return null;
}
var issuedAt = DateTimeOffset.FromUnixTimeSeconds(iat).DateTime;
if (issuedAt < user.TokenValidTime.ToUniversalTime())
var iatD = DateTimeOffset.FromUnixTimeSeconds(iat).ToUniversalTime().DateTime;
if (iatD < user.TokenValidTime)
return null;
UserCache = user;

View File

@@ -12,6 +12,7 @@ public class SessionService
private readonly IdentityService IdentityService;
private readonly NavigationManager NavigationManager;
private readonly AlertService AlertService;
private readonly DateTimeService DateTimeService;
private Session? OwnSession;
@@ -19,12 +20,14 @@ public class SessionService
SessionRepository sessionRepository,
IdentityService identityService,
NavigationManager navigationManager,
AlertService alertService)
AlertService alertService,
DateTimeService dateTimeService)
{
SessionRepository = sessionRepository;
IdentityService = identityService;
NavigationManager = navigationManager;
AlertService = alertService;
DateTimeService = dateTimeService;
}
public async Task Register()
@@ -36,7 +39,7 @@ public class SessionService
Ip = IdentityService.GetIp(),
Url = NavigationManager.Uri,
Device = IdentityService.GetDevice(),
CreatedAt = DateTime.Now,
CreatedAt = DateTimeService.GetCurrent(),
User = user,
Navigation = NavigationManager,
AlertService = AlertService
@@ -64,10 +67,8 @@ public class SessionService
{
foreach (var session in SessionRepository.Get())
{
if (session.User.Id == user.Id)
{
if(session.User != null && session.User.Id == user.Id)
session.Navigation.NavigateTo(session.Navigation.Uri, true);
}
}
}
}

View File

@@ -7,15 +7,17 @@ namespace Moonlight.App.Services.Statistics;
public class StatisticsViewService
{
private readonly StatisticsRepository StatisticsRepository;
private readonly DateTimeService DateTimeService;
public StatisticsViewService(StatisticsRepository statisticsRepository)
public StatisticsViewService(StatisticsRepository statisticsRepository, DateTimeService dateTimeService)
{
StatisticsRepository = statisticsRepository;
DateTimeService = dateTimeService;
}
public StatisticsData[] GetData(string chart, StatisticsTimeSpan timeSpan)
{
var startDate = DateTime.Now - TimeSpan.FromHours((int)timeSpan);
var startDate = DateTimeService.GetCurrent() - TimeSpan.FromHours((int)timeSpan);
var objs = StatisticsRepository.Get().Where(x => x.Date > startDate && x.Chart == chart);

View File

@@ -19,6 +19,7 @@ public class UserService
private readonly MailService MailService;
private readonly IdentityService IdentityService;
private readonly IpLocateService IpLocateService;
private readonly DateTimeService DateTimeService;
private readonly string JwtSecret;
@@ -29,7 +30,9 @@ public class UserService
SecurityLogService securityLogService,
AuditLogService auditLogService,
MailService mailService,
IdentityService identityService, IpLocateService ipLocateService)
IdentityService identityService,
IpLocateService ipLocateService,
DateTimeService dateTimeService)
{
UserRepository = userRepository;
TotpService = totpService;
@@ -38,6 +41,7 @@ public class UserService
MailService = mailService;
IdentityService = identityService;
IpLocateService = ipLocateService;
DateTimeService = dateTimeService;
JwtSecret = configService
.GetSection("Moonlight")
@@ -70,12 +74,12 @@ public class UserService
LastName = lastname,
State = "",
Status = UserStatus.Unverified,
CreatedAt = DateTime.UtcNow,
CreatedAt = DateTimeService.GetCurrent(),
DiscordId = 0,
TotpEnabled = false,
TotpSecret = "",
UpdatedAt = DateTime.UtcNow,
TokenValidTime = DateTime.Now.AddDays(-5)
UpdatedAt = DateTimeService.GetCurrent(),
TokenValidTime = DateTimeService.GetCurrent().AddDays(-5)
});
await MailService.SendMail(user!, "register", values => {});
@@ -168,7 +172,7 @@ public class UserService
public async Task ChangePassword(User user, string password, bool isSystemAction = false)
{
user.Password = BCrypt.Net.BCrypt.HashPassword(password);
user.TokenValidTime = DateTime.Now;
user.TokenValidTime = DateTimeService.GetCurrent();
UserRepository.Update(user);
if (isSystemAction)
@@ -244,8 +248,8 @@ public class UserService
var token = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(JwtSecret)
.AddClaim("exp", DateTimeOffset.UtcNow.AddDays(10).ToUnixTimeSeconds())
.AddClaim("iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds())
.AddClaim("exp", new DateTimeOffset(DateTimeService.GetCurrent().AddDays(10)).ToUnixTimeSeconds())
.AddClaim("iat", DateTimeService.GetCurrentUnixSeconds())
.AddClaim("userid", user.Id)
.Encode();

View File

@@ -104,6 +104,7 @@ namespace Moonlight
builder.Services.AddScoped<SmartDeployService>();
builder.Services.AddScoped<WebSpaceService>();
builder.Services.AddScoped<StatisticsViewService>();
builder.Services.AddSingleton<DateTimeService>();
builder.Services.AddScoped<GoogleOAuth2Service>();
builder.Services.AddScoped<DiscordOAuth2Service>();

View File

@@ -7,6 +7,7 @@
@using Moonlight.App.Services.Sessions
@inject UserRepository UserRepository
@inject UserService UserService
@inject SessionService SessionService
@inject ToastService ToastService
@inject SmartTranslateService SmartTranslateService
@@ -76,17 +77,27 @@
</div>
</div>
<div class="mt-5 card card-body p-10">
<div class="d-flex justify-content-end">
<a href="/admin/users" class="btn btn-danger me-3">
<TL>Cancel</TL>
</a>
<WButton Text="@(SmartTranslateService.Translate("Update"))"
WorkingText="@(SmartTranslateService.Translate("Updating"))"
CssClasses="btn-success"
OnClick="Update">
</WButton>
</div>
</div>
<div class="input-group">
<input @bind="NewPassword" type="password" class="form-control" placeholder="@(SmartTranslateService.Translate("Password"))"/>
<WButton Text="@(SmartTranslateService.Translate("Change"))"
WorkingText="@(SmartTranslateService.Translate("Reloading"))"
CssClasses="btn-primary"
OnClick="ChangePassword">
</WButton>
</div>
</div>
<div class="mt-5 card card-body p-10">
<div class="d-flex justify-content-end">
<a href="/admin/users" class="btn btn-danger me-3">
<TL>Cancel</TL>
</a>
<WButton Text="@(SmartTranslateService.Translate("Update"))"
WorkingText="@(SmartTranslateService.Translate("Updating"))"
CssClasses="btn-success"
OnClick="Update">
</WButton>
</div>
</div>
</div>
<div class="col-xl-6 mb-5 mb-xl-10">
<div class="card card-body p-10">
@@ -148,6 +159,8 @@
private User? User;
private string NewPassword = "";
private Task Load(LazyLoader arg)
{
User = UserRepository.Get().FirstOrDefault(x => x.Id == Id);
@@ -172,4 +185,14 @@
await ToastService.Success(SmartTranslateService.Translate("Successfully updated user"));
}
private async Task ChangePassword()
{
await UserService.ChangePassword(User!, NewPassword, true);
NewPassword = "";
SessionService.ReloadUserSessions(User);
await ToastService.Success(SmartTranslateService.Translate("Successfully updated password"));
}
}

View File

@@ -64,7 +64,7 @@
<Column TableItem="Session" Title="@(SmartTranslateService.Translate("Time"))" Field="@(x => x.CreatedAt)" Sortable="true" Filterable="true" Width="10%">
<Template>
@{
var time = Formatter.FormatUptime((DateTime.Now - context.CreatedAt).TotalMilliseconds);
var time = Formatter.FormatUptime((DateTime.UtcNow - context.CreatedAt).TotalMilliseconds);
}
<span>@(time)</span>
</Template>