Compare commits
No commits in common. "4f1d42453c89783b93da5f52e03a2f47a1d6864c" and "c2d89bb25390699052e32018bd8926691de4d7dc" have entirely different histories.
4f1d42453c
...
c2d89bb253
|
|
@ -6,12 +6,4 @@
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\AyCode.Utils\AyCode.Utils.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Enums\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,22 +0,0 @@
|
||||||
//using Anata.Logger;
|
|
||||||
|
|
||||||
namespace AyCode.Core.Consts
|
|
||||||
{
|
|
||||||
//TODO: Adatbázisból kéne a környezeti beállításokat - J.
|
|
||||||
public static class AcEnv
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Environment.NewLine
|
|
||||||
/// </summary>
|
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
public static string NL => Environment.NewLine;
|
|
||||||
|
|
||||||
//public static AppModeType AppModeServer = AppModeType.Trace;
|
|
||||||
////Elküldeni a kliens-nek, így szerver oldalról tudjuk szabályozni...
|
|
||||||
//public static AppModeType AppModeClient = AppModeType.Trace;
|
|
||||||
|
|
||||||
//public static LogLevel LogLevel = LogLevel.Detail;
|
|
||||||
|
|
||||||
public static ulong MaxLogItemsPerSession = 250;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
namespace AyCode.Core.Consts
|
|
||||||
{
|
|
||||||
public enum AcErrorCode : byte
|
|
||||||
{
|
|
||||||
Unset = 255,
|
|
||||||
|
|
||||||
//[DisplayName("Unknown error")]
|
|
||||||
UnknownError = 0,
|
|
||||||
InvalidMessage = 1,
|
|
||||||
SessionOpenFailed = 2,
|
|
||||||
ServerSideSessionOpenFailed = 3,
|
|
||||||
SessionNotFound = 4,
|
|
||||||
ServerSideSessionNotFound = 5,
|
|
||||||
DatabaseError = 6,
|
|
||||||
UserNameInUse = 7,
|
|
||||||
EmailInUse = 8,
|
|
||||||
UserAlreadyLoggedIn = 9,
|
|
||||||
WrongLoginData = 10,
|
|
||||||
UserWasntLoggedIn = 11,
|
|
||||||
NotAllowedMethod = 12,
|
|
||||||
EmailSendError = 13,
|
|
||||||
RoomFullOrHasStarted = 14,
|
|
||||||
UserIsLockOut = 15,
|
|
||||||
ClientVersionNotValid = 16,
|
|
||||||
PermissionTagDenied = 17,
|
|
||||||
RequestedGetItemNotfound = 18,
|
|
||||||
RequestedPostError = 19,
|
|
||||||
RequestedEditError = 20,
|
|
||||||
RequestedDeleteError = 21,
|
|
||||||
NotAllowedUserId = 22,
|
|
||||||
NotAllowedPlayerId = 23,
|
|
||||||
IdIsNullOrEmpty = 24,
|
|
||||||
IdNotFound = 25,
|
|
||||||
EntityIsNull = 26,
|
|
||||||
UserNameIsTooShort = 27,
|
|
||||||
PasswordIsTooShort = 28,
|
|
||||||
EmailFormatIsNotValid = 29,
|
|
||||||
UserTokenIsNotValid = 30,
|
|
||||||
ConsentNotAccepted = 31,
|
|
||||||
UserNameNotFound = 32,
|
|
||||||
PlayerNotFoundForUser = 33,
|
|
||||||
MarketItemExistsWithSameName = 34,
|
|
||||||
PlayerNameInUse = 35,
|
|
||||||
PlayerNameIsTooShort = 36,
|
|
||||||
ConfirmationPasswordNotValid = 37,
|
|
||||||
|
|
||||||
RegionPlayerMaxLimit = 38,
|
|
||||||
OwnerIsNotSpawnedInRegion = 39,
|
|
||||||
RegionDataNotFound = 40,
|
|
||||||
RegionNotFound = 41,
|
|
||||||
|
|
||||||
BrandIdNotFound = 42,
|
|
||||||
DomainIdNotFound = 43,
|
|
||||||
|
|
||||||
DisableAddUser = 44,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
using AyCode.Utils.Extensions;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace AyCode.Core.Consts
|
|
||||||
{
|
|
||||||
public static class AcValidate
|
|
||||||
{
|
|
||||||
public static bool IsValidUserNameAndPasswordFormat(string username, string password, out AcErrorCode acErrorCode)
|
|
||||||
{
|
|
||||||
return IsValidUserNameFormat(username, out acErrorCode) && IsValidPasswordFormat(password, out acErrorCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsValidUserNameFormat(string userName, out AcErrorCode acErrorCode)
|
|
||||||
{
|
|
||||||
acErrorCode = AcErrorCode.Unset;
|
|
||||||
|
|
||||||
var isValid = !userName.IsNullOrWhiteSpace() && userName.Length is >= AcConst.MinUserNameLength and <= AcConst.MaxUserNameLength && userName.Trim() == userName;
|
|
||||||
|
|
||||||
if (!isValid) acErrorCode = AcErrorCode.UserNameIsTooShort;
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsValidPlayerNameFormat(string playerName, out AcErrorCode acErrorCode)
|
|
||||||
{
|
|
||||||
acErrorCode = AcErrorCode.Unset;
|
|
||||||
|
|
||||||
var isValid = !playerName.IsNullOrWhiteSpace() && playerName.Length is >= AcConst.MinPlayerNameLength and <= AcConst.MaxPlayerNameLength && playerName.Trim() == playerName;
|
|
||||||
|
|
||||||
if (!isValid) acErrorCode = AcErrorCode.PlayerNameIsTooShort;
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsValidPasswordFormat(string password, out AcErrorCode acErrorCode)
|
|
||||||
{
|
|
||||||
acErrorCode = AcErrorCode.Unset;
|
|
||||||
|
|
||||||
var isValid = !password.IsNullOrWhiteSpace() && password.Length is >= AcConst.MinPasswordLength and <= AcConst.MaxPasswordLength;
|
|
||||||
|
|
||||||
if (!isValid) acErrorCode = AcErrorCode.PasswordIsTooShort;
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsValidEmailFormat(string email, out AcErrorCode acErrorCode)
|
|
||||||
{
|
|
||||||
acErrorCode = AcErrorCode.Unset;
|
|
||||||
|
|
||||||
//a@a.a -> length == 5
|
|
||||||
var isValid = !email.IsNullOrWhiteSpace() && email.Length >= 5 && email.Contains('@') && email.Contains('.') && !email.Contains(' ');
|
|
||||||
|
|
||||||
if (!isValid) acErrorCode = AcErrorCode.EmailFormatIsNotValid;
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsValidUserTokenFormat(string verificationToken, out AcErrorCode acErrorCode)
|
|
||||||
{
|
|
||||||
acErrorCode = AcErrorCode.Unset;
|
|
||||||
|
|
||||||
var isValid = !verificationToken.IsNullOrWhiteSpace() && verificationToken.Length is >= AcConst.MinUserTokenLength and <= AcConst.MaxUserTokenLength;
|
|
||||||
|
|
||||||
if (!isValid) acErrorCode = AcErrorCode.UserTokenIsNotValid;
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsValidDomain(string domainName)
|
|
||||||
{
|
|
||||||
var suffixes = string.Join('|', AcConst.AvailableDomainSuffixes);
|
|
||||||
var regexp = new Regex("^[a-z0-9]{3,90}\\.(" + suffixes + ")$"); // a pattern-t vegyük ki konstansba a dll-re - B.
|
|
||||||
var match = regexp.IsMatch(domainName);
|
|
||||||
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
namespace AyCode.Core.Helpers
|
|
||||||
{
|
|
||||||
public static class TaskHelper
|
|
||||||
{
|
|
||||||
public static bool WaitTo(Func<bool> predicate, int msTimeout = 10000, int msDelay = 5)
|
|
||||||
=> WaitToAsync(predicate, msTimeout, msDelay).GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
public static Task<bool> WaitToAsync(Func<bool> predicate, int msTimeout = 10000, int msDelay = 5)
|
|
||||||
{
|
|
||||||
return ToThreadPoolTask(async () =>
|
|
||||||
{
|
|
||||||
var result = false;
|
|
||||||
var dtTimeout = DateTime.UtcNow.AddMilliseconds(msTimeout).Ticks;
|
|
||||||
|
|
||||||
while (dtTimeout > DateTime.UtcNow.Ticks && !(result = predicate()))
|
|
||||||
await Task.Delay(msDelay).ConfigureAwait(false); //Thread.Sleep(msDelay);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Forget(this Task task)
|
|
||||||
{
|
|
||||||
if (!task.IsCompleted || task.IsFaulted)
|
|
||||||
_ = ForgetAwaited(task);
|
|
||||||
|
|
||||||
static async Task ForgetAwaited(Task task)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await task.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await Task.FromException(ex).ConfigureAwait(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//public static void Forget(this ValueTask task)
|
|
||||||
//{
|
|
||||||
// if (!task.IsCompleted || task.IsFaulted)
|
|
||||||
// _ = ForgetAwaited(task);
|
|
||||||
|
|
||||||
// static async ValueTask ForgetAwaited(ValueTask task)
|
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// await task.ConfigureAwait(false);
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// //TODO: .net5, .net6 feature! - J.
|
|
||||||
// ValueTask.FromException(ex).ConfigureAwait(true);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//TODO: Cancellation token params - J.
|
|
||||||
//public static void RunOnThreadPool(this Task task) => Task.Run(() => _ = task).Forget(); //TODO: Letesztelni, a ThreadId-kat! - J.
|
|
||||||
public static void RunOnThreadPool(this Action action) => ToThreadPoolTask(action).Forget();
|
|
||||||
public static void RunOnThreadPool<T>(this Func<T> func) => ToThreadPoolTask(func).Forget();
|
|
||||||
public static Task ToThreadPoolTask(this Action action) => Task.Run(action);
|
|
||||||
//public static Task ToThreadPoolTask(this Task task) => Task.Run(() => _ = task);
|
|
||||||
//public static void ToParallelTaskStart(this Task task) => task.Start();
|
|
||||||
//public static Task<T> ToThreadPoolTask<T>(this Task<T> task) => Task.Run(() => task);
|
|
||||||
public static Task<T> ToThreadPoolTask<T>(this Func<Task<T>> func) => Task.Run(func); //TODO: Letesztelni, a ThreadId-kat! - J.
|
|
||||||
public static Task<T> ToThreadPoolTask<T>(this Func<T> func) => Task.Run(func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AyCode.Core.Consts;
|
|
||||||
|
|
||||||
namespace AyCode.Core.Logger
|
|
||||||
{
|
|
||||||
public static class Logger
|
|
||||||
{
|
|
||||||
public static void Info(string text)
|
|
||||||
{
|
|
||||||
Console.WriteLine(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Warning(string text)
|
|
||||||
{
|
|
||||||
Console.WriteLine(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Error(string text)
|
|
||||||
{
|
|
||||||
Console.WriteLine(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Error(string text, Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{text}{AcEnv.NL}{ex.Message}{AcEnv.NL}{ex}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -30,8 +30,4 @@
|
||||||
<ProjectReference Include="..\AyCode.Interfaces\AyCode.Interfaces.csproj" />
|
<ProjectReference Include="..\AyCode.Interfaces\AyCode.Interfaces.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="UserTokens\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
using AyCode.Core.Tests;
|
using AyCode.Core.Tests;
|
||||||
using AyCode.Database.DataLayers;
|
|
||||||
using AyCode.Database.DbContexts;
|
using AyCode.Database.DbContexts;
|
||||||
|
|
||||||
namespace AyCode.Database.Tests;
|
namespace AyCode.Database.Tests;
|
||||||
|
|
||||||
public abstract class DatabaseTestModelBase<TDbContext> : TestModelBase where TDbContext : DbContextBase
|
//public abstract class DatabaseTestModelBase<TDal> : TestModelBase where TDal : DbContextBase
|
||||||
|
public abstract class DatabaseTestModelBase : TestModelBase
|
||||||
{
|
{
|
||||||
protected DatabaseTestModelBase()
|
protected DatabaseTestModelBase()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
|
|
||||||
namespace AyCode.Database.Tests
|
namespace AyCode.Database.Tests
|
||||||
{
|
{
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public abstract class DatabaseTests : DatabaseTestModelBase<DbContextBase>
|
public abstract class DatabaseTests : DatabaseTestModelBase
|
||||||
{
|
{
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestMethod1()
|
public void TestMethod1()
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
using AyCode.Database.DbContexts.Users;
|
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
|
|
||||||
namespace AyCode.Database.Tests.Users
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public abstract class UserDbSetTest<TDbContext, TUser, TUserToken> : DatabaseTestModelBase<TDbContext>
|
|
||||||
where TDbContext : DbContextBase, IUserDbContextBase<TUser, TUserToken>
|
|
||||||
where TUser : class, IUserBase
|
|
||||||
where TUserToken : class, IUserTokenBase
|
|
||||||
|
|
||||||
{
|
|
||||||
//UserDalBase<UserDbContext, User, UserTokenBase>
|
|
||||||
//private UserDal _userDal;
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TearDown()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//[TestMethod]
|
|
||||||
//[DataRow("test@tiam.hu")]
|
|
||||||
//public void GetUserByEmail_ReturnsUser_WhenUserExists(string email)
|
|
||||||
//{
|
|
||||||
// //var userDal = PooledDal.CreateDal<UserDal>();
|
|
||||||
// var user = _userDal.GetUserByEmail(email);
|
|
||||||
|
|
||||||
// Assert.IsNotNull(user);
|
|
||||||
// Assert.AreEqual(email, user.EmailAddress);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AyCode.Database.DbContexts;
|
||||||
|
using AyCode.Utils.Extensions;
|
||||||
|
|
||||||
|
namespace AyCode.Database;
|
||||||
|
|
||||||
|
public class DalBase<TDbContext> where TDbContext : DbContextBase
|
||||||
|
{
|
||||||
|
public string Name { get; private set; }
|
||||||
|
private TDbContext _ctx;
|
||||||
|
public TDbContext Ctx => _ctx;
|
||||||
|
|
||||||
|
public DalBase() : this(Activator.CreateInstance<TDbContext>())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public DalBase(TDbContext ctx)
|
||||||
|
{
|
||||||
|
_ctx = ctx;
|
||||||
|
|
||||||
|
if (_ctx.Name.IsNullOrWhiteSpace())
|
||||||
|
_ctx.Name = _ctx.GetType().Name;
|
||||||
|
|
||||||
|
Name = $"{this.GetType().Name}, {_ctx.Name}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AyCode.Core.Helpers;
|
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
using AyCode.Database.Extensions;
|
|
||||||
using AyCode.Interfaces.Entities;
|
|
||||||
using AyCode.Utils.Extensions;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DataLayers;
|
|
||||||
|
|
||||||
public abstract class DalBase<TDbContext> : IDalBase<TDbContext> where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
public string Name { get; private set; }
|
|
||||||
|
|
||||||
public bool AutoCloseSession { get; set; }
|
|
||||||
|
|
||||||
public TDbContext Context { get; private set; }
|
|
||||||
|
|
||||||
//protected DalBase()
|
|
||||||
//{
|
|
||||||
// Name = $"{GetType().Name}";
|
|
||||||
//}
|
|
||||||
|
|
||||||
protected DalBase() : this(Activator.CreateInstance<TDbContext>())
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected DalBase(TDbContext ctx)
|
|
||||||
{
|
|
||||||
Context = ctx;
|
|
||||||
|
|
||||||
if (Context.Name.IsNullOrWhiteSpace())
|
|
||||||
Context.Name = Context.GetType().Name;
|
|
||||||
|
|
||||||
Name = $"{GetType().Name}, {Context.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public TDbContext CreateDbContext()
|
|
||||||
{
|
|
||||||
return Activator.CreateInstance<TDbContext>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CloseDbContext(ref TDbContext? ctx)
|
|
||||||
{
|
|
||||||
ctx?.Dispose();
|
|
||||||
ctx = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<TResultType> SessionAsync<TResultType>(Func<TDbContext, TResultType> callback)
|
|
||||||
=> this.SessionAsync<TDbContext, TResultType>(callback);
|
|
||||||
|
|
||||||
public Task<IEnumerable<TEntity>> SessionAsync<TEntity>(Func<TDbContext, IQueryable<TEntity>> callback) where TEntity : IEntity
|
|
||||||
=> this.SessionAsync<TDbContext, TEntity>(callback);
|
|
||||||
|
|
||||||
public TResultType Session<TResultType>(Func<TDbContext, TResultType> callback)
|
|
||||||
=> this.Session<TDbContext, TResultType>(callback);
|
|
||||||
|
|
||||||
public IEnumerable<TEntity> Session<TEntity>(Func<TDbContext, IQueryable<TEntity>> callback) where TEntity : IEntity
|
|
||||||
=> this.Session<TDbContext, TEntity>(callback);
|
|
||||||
|
|
||||||
public Task<bool> TransactionAsync(Func<TDbContext, bool> callbackTransactionBody, bool throwException = false)
|
|
||||||
=> this.TransactionAsync<TDbContext>(callbackTransactionBody, throwException);
|
|
||||||
|
|
||||||
public bool Transaction(Func<TDbContext, bool> callbackTransactionBody, bool throwException = false)
|
|
||||||
=> this.Transaction<TDbContext>(callbackTransactionBody, throwException);
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
//public void Dispose()
|
|
||||||
//{
|
|
||||||
// Ctx?.Dispose();
|
|
||||||
// Ctx = null;
|
|
||||||
|
|
||||||
// //CloseDbContext(ref Ctx);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DataLayers;
|
|
||||||
|
|
||||||
public interface IDalBase //: IDisposable
|
|
||||||
{
|
|
||||||
public string Name { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IDalBase<TDbContext> : IDalBase where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
public bool AutoCloseSession { get; set; }
|
|
||||||
public TDbContext Context { get; }
|
|
||||||
|
|
||||||
public TDbContext CreateDbContext();
|
|
||||||
public void CloseDbContext(ref TDbContext? ctx);
|
|
||||||
}
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using AyCode.Utils.Extensions;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DataLayers
|
|
||||||
{
|
|
||||||
public sealed class PooledDal
|
|
||||||
{
|
|
||||||
private static readonly PooledDal Instance = new();
|
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<Guid, ConcurrentDictionary<Type, IDalBase>> _dataLayersPoolById = new();
|
|
||||||
private static ConcurrentDictionary<Guid, ConcurrentDictionary<Type, IDalBase>> DataLayersPoolById => Instance._dataLayersPoolById;
|
|
||||||
|
|
||||||
public static int Count => DataLayersPoolById.Count;
|
|
||||||
public static void Clear() => DataLayersPoolById.Clear();
|
|
||||||
|
|
||||||
public static TDal CreateDal<TDal>() where TDal : IDalBase => Activator.CreateInstance<TDal>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDal"></typeparam>
|
|
||||||
/// <param name="id">ONLY SessionId or logged in PlayerId!</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static TDal GetDalById<TDal>(Guid id) where TDal : IDalBase
|
|
||||||
{
|
|
||||||
if (id.IsNullOrEmpty()) return CreateDal<TDal>(); //TODO: A Guid.Empty id-t ÁTGONDOLNI! - J.
|
|
||||||
|
|
||||||
if (DataLayersPoolById.TryGetValue(id, out var dataLayersByType))
|
|
||||||
return GetDalByType<TDal>(dataLayersByType);
|
|
||||||
|
|
||||||
dataLayersByType = new ConcurrentDictionary<Type, IDalBase>();
|
|
||||||
DataLayersPoolById.TryAdd(id, dataLayersByType);
|
|
||||||
|
|
||||||
return GetDalByType<TDal>(dataLayersByType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TDal GetDalByType<TDal>(ConcurrentDictionary<Type, IDalBase> dataLayersByType) where TDal : IDalBase
|
|
||||||
{
|
|
||||||
if (dataLayersByType.TryGetValue(typeof(TDal), out var dataLayer))
|
|
||||||
return (TDal)dataLayer;
|
|
||||||
|
|
||||||
var resultDal = CreateDal<TDal>();
|
|
||||||
dataLayersByType.TryAdd(typeof(TDal), resultDal);
|
|
||||||
|
|
||||||
return resultDal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">SessionId or PlayerId</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static bool Remove(Guid id)//, bool keepGuidEmptyId = true)
|
|
||||||
{
|
|
||||||
//if (keepGuidEmptyId && id == Guid.Empty) return false;
|
|
||||||
|
|
||||||
if (!DataLayersPoolById.TryRemove(id, out var dataLayersByType))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
dataLayersByType.Clear();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,212 +0,0 @@
|
||||||
using System.Diagnostics;
|
|
||||||
using AyCode.Core;
|
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
using AyCode.Database.DbContexts.Users;
|
|
||||||
using AyCode.Database.DbSets.Users;
|
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DataLayers.Users
|
|
||||||
{
|
|
||||||
public static class AcUserDalExtension
|
|
||||||
{
|
|
||||||
//public static bool DeleteUser(this IUserDbContextBase ctx, IUserBase user)
|
|
||||||
//{
|
|
||||||
// if (user == null) return false;
|
|
||||||
|
|
||||||
// var players = ctx.Players.Where(x => x.OwnerId == user.Id).ToList();
|
|
||||||
|
|
||||||
// foreach (var player in players)
|
|
||||||
// {
|
|
||||||
// ctx.Profiles.RemoveRange(ctx.Profiles.Where(x => x.OwnerId == player.PlayerId || x.OwnerId == user.Id));
|
|
||||||
// ctx.Wallets.RemoveRange(ctx.Wallets.Where(x => x.OwnerId == player.PlayerId || x.OwnerId == user.Id));
|
|
||||||
|
|
||||||
// ctx.Sessions.RemoveRange(ctx.Sessions.Where(x => x.PlayerId == player.PlayerId));
|
|
||||||
// //ctx.SessionDetails.RemoveRange(ctx.SessionDetails.Where(x => x.PlayerId == player.PlayerId));
|
|
||||||
|
|
||||||
// ctx.PlayerPermissionTags.RemoveRange(player.PermissionTags);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ctx.Players.RemoveRange(players);
|
|
||||||
// ctx.UserTokens.RemoveRange(ctx.UserTokens.Where(x => x.UserId == user.Id));
|
|
||||||
// //ctx.PermissionCategory.RemoveRange(ctx.PermissionCategory.Where(x => x.ForeignKey == user.Id));
|
|
||||||
|
|
||||||
// ctx.SaveChanges(); //A Player constraint miatt kell, különben nem engedi törölni a User-t! - J.
|
|
||||||
// return ctx.Remove(user).State == EntityState.Deleted;
|
|
||||||
//}
|
|
||||||
|
|
||||||
public static TUser? GetUserById<TUser>(this IUserDbSet<TUser> ctx, Guid userId) where TUser : class, IUserBase
|
|
||||||
{
|
|
||||||
return ctx.Users.FirstOrDefault(u => u.Id == userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TUser? GetUserByEmail<TUser>(this IUserDbSet<TUser> ctx, string email) where TUser : class, IUserBase
|
|
||||||
{
|
|
||||||
var emailLower = email.ToLower();
|
|
||||||
return ctx.Users.FirstOrDefault(u => u.EmailAddress == emailLower);
|
|
||||||
}
|
|
||||||
|
|
||||||
//public static IEnumerable<UserToUserConsent> GetUserConsentsByUserId(this UserDbContextBase ctx, Guid userId)
|
|
||||||
// => ctx.UserToUserConsents.Where(u => u.UserId == userId);
|
|
||||||
|
|
||||||
//public static bool IsUserConsentsAccepted(this UserDbContextBase ctx, Guid userId)
|
|
||||||
// => ctx.GetUserConsentsByUserId(userId).Count(x => x.IsAccepted) == AcConst.ConsentCount;
|
|
||||||
|
|
||||||
//public static bool SetUserConsentsToAccepted(this UserDbContextBase ctx, Guid userId)
|
|
||||||
//{
|
|
||||||
// var user = ctx.GetUserById(userId);
|
|
||||||
// return ctx.SetUserConsentsToAccepted(user);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public static bool SetUserConsentsToAccepted(this UserDbContextBase ctx, IUserBase? user)
|
|
||||||
//{
|
|
||||||
// if (!user.EmailConfirmed) return false; //Ez nem kéne ide... - J.
|
|
||||||
|
|
||||||
// var hashSet = ctx.GetUserConsentsByUserId(user.Id).Select(x => x.UserConsentId).ToHashSet();
|
|
||||||
// var userConsents = ctx.UserConsents.Where(x => !hashSet.Contains(x.Id));
|
|
||||||
|
|
||||||
// ctx.AddRange(userConsents.Select(userConsent => new UserToUserConsent(user.Id, userConsent.Id, true)));
|
|
||||||
|
|
||||||
// var userToUserConsents = ctx.GetUserConsentsByUserId(user.Id).Where(x => !x.IsAccepted).ToList();
|
|
||||||
// foreach (var userToUserConsent in userToUserConsents)
|
|
||||||
// {
|
|
||||||
// userToUserConsent.IsAccepted = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ctx.UpdateRange(userToUserConsents);
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
public static bool ChangePassword<TUser, TUserToken>(this IUserDbContextBase<TUser, TUserToken> ctx, TUser? user, string passwordHash, string verificationToken)
|
|
||||||
where TUser : class, IUserBase
|
|
||||||
where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
if (user == null || !ctx.IsValidToken(user.Id, verificationToken)) return false;
|
|
||||||
|
|
||||||
user.Password = passwordHash;
|
|
||||||
ctx.Users.Update(user);
|
|
||||||
|
|
||||||
ctx.DeactivateTokens(user.Id);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TUserToken? UpdateUserTokenSent<TUserToken>(this IUserTokenDbSet<TUserToken> ctx, Guid userId, string verificationToken, DateTime tokenSentUtc) where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
var userToken = ctx.GetUserToken(userId, verificationToken);
|
|
||||||
|
|
||||||
if (userToken == null) return null;
|
|
||||||
|
|
||||||
userToken.TokenSent = tokenSentUtc;
|
|
||||||
userToken.TokenExpiration ??= tokenSentUtc.AddDays(1);
|
|
||||||
|
|
||||||
var utcNow = DateTime.UtcNow;
|
|
||||||
userToken.IsActive = tokenSentUtc <= utcNow && userToken.TokenExpiration > utcNow;
|
|
||||||
|
|
||||||
ctx.UserTokens.Update(userToken);
|
|
||||||
return userToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TUserToken CreateUserToken<TUserToken>(this IUserTokenDbSet<TUserToken> ctx, Guid userId, string verificationToken) where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
var userToken = Activator.CreateInstance<TUserToken>();
|
|
||||||
userToken.UserId = userId;
|
|
||||||
userToken.Token = verificationToken;
|
|
||||||
|
|
||||||
return ctx.CreateUserToken(userToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TUserToken CreateUserToken<TUserToken>(this IUserTokenDbSet<TUserToken> ctx, TUserToken userToken) where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
ctx.DeactivateTokens(userToken.UserId);
|
|
||||||
|
|
||||||
userToken.IsActive = true;
|
|
||||||
ctx.UserTokens.Add(userToken);
|
|
||||||
|
|
||||||
return userToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TUserToken? GetActiveUserToken<TUserToken>(this IUserTokenDbSet<TUserToken> ctx, Guid userId) where TUserToken : class, IUserTokenBase
|
|
||||||
=> ctx.UserTokens.SingleOrDefault(x => x.UserId == userId && x.IsActive && (x.TokenExpiration == null || x.TokenExpiration > DateTime.UtcNow));
|
|
||||||
|
|
||||||
public static TUserToken? GetUserToken<TUserToken>(this IUserTokenDbSet<TUserToken> ctx, Guid userId, string verificationToken) where TUserToken : class?, IUserTokenBase?
|
|
||||||
=> ctx.UserTokens.SingleOrDefault(x => x.UserId == userId && x.Token == verificationToken);
|
|
||||||
|
|
||||||
public static bool IsValidToken<TUserToken>(this IUserTokenDbSet<TUserToken> ctx, Guid userId, string verificationToken) where TUserToken : class, IUserTokenBase
|
|
||||||
=> ctx.UserTokens.Any(x => x.UserId == userId && x.IsActive && x.Token == verificationToken && x.TokenExpiration > DateTime.UtcNow && x.TokenSent < DateTime.UtcNow);
|
|
||||||
|
|
||||||
public static void DeactivateTokens<TUserToken>(this IUserTokenDbSet<TUserToken> ctx, Guid userId) where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
var activeUserTokens = ctx.UserTokens.Where(x => x.UserId == userId && x.IsActive);
|
|
||||||
|
|
||||||
foreach (var activeUserToken in activeUserTokens)
|
|
||||||
activeUserToken.IsActive = false;
|
|
||||||
|
|
||||||
ctx.UserTokens.UpdateRange(activeUserTokens);
|
|
||||||
}
|
|
||||||
|
|
||||||
////public static void GetUserDetails(this IUserDal userDal, Guid userId, Action<AspNetUser> callback)
|
|
||||||
//// => callback(userDal.Get<AspNetUser>(userId));
|
|
||||||
|
|
||||||
//public static void UsernameAndEmailAvailable(this IUserDal userDal, string username, string email, Action<bool, AcErrorCode, AspNetUser> callback)
|
|
||||||
//{
|
|
||||||
// IUserBase notConfirmedUser = null;
|
|
||||||
|
|
||||||
// var lowerEmail = email.ToLower();
|
|
||||||
// var lowerUserName = username.ToLower();
|
|
||||||
|
|
||||||
// var isAvailable = AcValidate.IsValidEmailFormat(lowerEmail, out var resultErrorCode) && AcValidate.IsValidUserNameFormat(lowerUserName, out resultErrorCode);
|
|
||||||
|
|
||||||
// if (isAvailable)
|
|
||||||
// {
|
|
||||||
// //userDal.RowCount<AspNetUser>(ctx => ctx.EmailConfirmed && (ctx.NormalizedUserName == lowerUserName || ctx.NormalizedEmail == lowerEmail)) == 0
|
|
||||||
|
|
||||||
// var users = userDal.Where<AspNetUser>(ctx => ctx.NormalizedUserName == lowerUserName || ctx.NormalizedEmail == lowerEmail).ToList();
|
|
||||||
|
|
||||||
// notConfirmedUser = users.FirstOrDefault(x => !x.EmailConfirmed && x.NormalizedEmail == lowerEmail);
|
|
||||||
|
|
||||||
// //isAvailable = (users.Count == 0 || (users.Count == 1 && notConfirmedUser != null));
|
|
||||||
|
|
||||||
// if (users.Count > 1) resultErrorCode = AcErrorCode.EmailInUse;
|
|
||||||
// else if (users.Count == 1 && notConfirmedUser == null)
|
|
||||||
// {
|
|
||||||
// resultErrorCode = users.Any(x => x.NormalizedEmail == lowerEmail) ? AcErrorCode.EmailInUse : AcErrorCode.UserNameInUse;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// isAvailable = resultErrorCode == AcErrorCode.Unset;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// callback(isAvailable, resultErrorCode, notConfirmedUser);
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//public static void AddNewUser(this IUserDal userDal, IUserBase newUser, Action<AspNetUser> callback)
|
|
||||||
//{
|
|
||||||
// userDal.Add(newUser);
|
|
||||||
// callback(newUser);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public static void AddNewUser(this IUserDal userDal, Guid userId, string username, string email, string password, Action callback)
|
|
||||||
//{
|
|
||||||
// var newUser = new AspNetUser(userId, username, email, password);
|
|
||||||
// userDal.Add(newUser);
|
|
||||||
|
|
||||||
// callback();
|
|
||||||
//}
|
|
||||||
|
|
||||||
////public static void DeleteUser(this IUserDal userDal, string username, Action callback)
|
|
||||||
////{
|
|
||||||
//// userDal.Session(ctx =>
|
|
||||||
//// {
|
|
||||||
//// var user = ctx.Users.FirstOrDefault(u => u.NormalizedUserName == username.ToUpperInvariant());
|
|
||||||
//// if (user == null) return;
|
|
||||||
|
|
||||||
//// ctx.Set<AspNetUser>().Delete(user);
|
|
||||||
//// ctx.SaveChanges();
|
|
||||||
//// };
|
|
||||||
////}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
using AyCode.Database.DbContexts.Users;
|
|
||||||
using AyCode.Entities.Users;
|
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using AyCode.Database.Extensions;
|
|
||||||
using AyCode.Core.Consts;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DataLayers.Users
|
|
||||||
{
|
|
||||||
public abstract class UserDalBase<TDbContext, TUser, TUserToken> : DalBase<TDbContext>, IUserDbContextBase<TUser, TUserToken>
|
|
||||||
where TDbContext : DbContextBase, IUserDbContextBase<TUser, TUserToken>
|
|
||||||
where TUser : class, IUserBase
|
|
||||||
where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
public DbSet<TUser> Users { get; set; }
|
|
||||||
public DbSet<TUserToken> UserTokens { get; set; }
|
|
||||||
|
|
||||||
public TUser? GetUserById(Guid userId) => Session(x => x.GetUserById(userId));
|
|
||||||
public Task<TUser?> GetUserByIdAsync(Guid userId) => SessionAsync(x => x.GetUserById(userId));
|
|
||||||
|
|
||||||
public TUser? GetUserByEmail(string email) => Session(x => x.GetUserByEmail(email));
|
|
||||||
public Task<TUser?> GetUserByEmailAsync(string email) => SessionAsync(x => x.GetUserByEmail(email));
|
|
||||||
|
|
||||||
//public UserToken CreateUserToken(Guid userId, string verificationToken)
|
|
||||||
//{
|
|
||||||
// UserToken userToken = null;
|
|
||||||
// Transaction(ctx =>
|
|
||||||
// {
|
|
||||||
// userToken = ctx.CreateUserToken(userId, verificationToken);
|
|
||||||
// return userToken != null;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
// return userToken;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public UserToken UpdateUserTokenSent(Guid userId, string verificationToken, DateTime tokenSentUtc)
|
|
||||||
//{
|
|
||||||
// UserToken userToken = null;
|
|
||||||
// Transaction(ctx =>
|
|
||||||
// {
|
|
||||||
// userToken = ctx.UpdateUserTokenSent(userId, verificationToken, tokenSentUtc);
|
|
||||||
// return userToken != null;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
// return userToken;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public UserToken GetActiveUserToken(Guid userId)
|
|
||||||
// => Session(ctx => ctx.GetActiveUserToken(userId));
|
|
||||||
|
|
||||||
//public UserToken GetUserToken(Guid userId, string verificationToken)
|
|
||||||
// => Session(ctx => ctx.GetUserToken(userId, verificationToken));
|
|
||||||
|
|
||||||
//public bool IsValidToken(Guid userId, string verificationToken)
|
|
||||||
// => Transaction(ctx => ctx.IsValidToken(userId, verificationToken));
|
|
||||||
|
|
||||||
//public bool IsValidToken(string email, string verificationToken)
|
|
||||||
//{
|
|
||||||
// return Transaction(ctx =>
|
|
||||||
// {
|
|
||||||
// var user = ctx.GetUserByEmail(email);
|
|
||||||
|
|
||||||
// return user != null && ctx.IsValidToken(user.Id, verificationToken);
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public void DeactivateTokens(Guid userId)
|
|
||||||
//{
|
|
||||||
// Transaction(ctx =>
|
|
||||||
// {
|
|
||||||
// ctx.DeactivateTokens(userId);
|
|
||||||
// return true;
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
//public string GetValidVerificationToken(UserDal userDal, Guid userId, out UserToken userToken)
|
|
||||||
//{
|
|
||||||
// string verificationToken;
|
|
||||||
// userToken = userDal.GetActiveUserToken(userId);
|
|
||||||
|
|
||||||
// if (userToken == null)
|
|
||||||
// {
|
|
||||||
// verificationToken = AntGenerator.NewToken();
|
|
||||||
// userToken = userDal.CreateUserToken(userId, verificationToken);
|
|
||||||
// }
|
|
||||||
// else verificationToken = userToken.Token;
|
|
||||||
|
|
||||||
// return verificationToken;
|
|
||||||
//}
|
|
||||||
|
|
||||||
public AcErrorCode GetUserForEmailValidation(string email, Func<TUser?, AcErrorCode, AcErrorCode> callback)
|
|
||||||
{
|
|
||||||
TUser? user = null;
|
|
||||||
var errorCodes = AcErrorCode.Unset;
|
|
||||||
|
|
||||||
Transaction(ctx =>
|
|
||||||
{
|
|
||||||
var lowerEmail= email.ToLower();
|
|
||||||
|
|
||||||
user = ctx.Users.FirstOrDefault(x => x.EmailAddress == lowerEmail && x.EmailConfirmed);
|
|
||||||
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
errorCodes = AcErrorCode.UserNameNotFound;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//user.Profile = ctx.Profiles.FirstOrDefault(x => x.OwnerId == user.Id);
|
|
||||||
|
|
||||||
//if (!ctx.IsUserConsentsAccepted(user.Id)) errorCodes = AcErrorCode.ConsentNotAccepted;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
//if (user != null)
|
|
||||||
|
|
||||||
return callback(user, errorCodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -32,27 +32,6 @@ public class DbContextBase : DbContext
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int SaveChanges()
|
public override int SaveChanges()
|
||||||
{
|
|
||||||
UpdateTimeStampInfoProperties();
|
|
||||||
|
|
||||||
return base.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
|
||||||
UpdateTimeStampInfoProperties();
|
|
||||||
|
|
||||||
return base.SaveChangesAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
|
||||||
UpdateTimeStampInfoProperties();
|
|
||||||
|
|
||||||
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateTimeStampInfoProperties()
|
|
||||||
{
|
{
|
||||||
var entries = ChangeTracker.Entries().Where(e =>
|
var entries = ChangeTracker.Entries().Where(e =>
|
||||||
e.Entity is not ITimeStampDisableAutoSet && (e is { State: EntityState.Added, Entity: ITimeStampCreated } || e.State is EntityState.Modified or EntityState.Added && e.Entity is ITimeStampModified));
|
e.Entity is not ITimeStampDisableAutoSet && (e is { State: EntityState.Added, Entity: ITimeStampCreated } || e.State is EntityState.Modified or EntityState.Added && e.Entity is ITimeStampModified));
|
||||||
|
|
@ -69,6 +48,8 @@ public class DbContextBase : DbContext
|
||||||
if (entityEntry.Entity is ITimeStampCreated timeStampCreated)
|
if (entityEntry.Entity is ITimeStampCreated timeStampCreated)
|
||||||
timeStampCreated.Created = utcNow;
|
timeStampCreated.Created = utcNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return base.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
using AyCode.Database.DbSets.Users;
|
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DbContexts.Users;
|
|
||||||
|
|
||||||
public interface IUserDbContextBase<TUser, TUserToken> : IUserDbSet<TUser>, IUserTokenDbSet<TUserToken> where TUser : class, IUserBase where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DbContexts.Users;
|
|
||||||
|
|
||||||
public interface IUserTokenDbContextBase<TUserToken> where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
DbSet<TUserToken> UserToken { get; set; }
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DbContexts.Users
|
|
||||||
{
|
|
||||||
public abstract class UserDbContextBase<TUser, TUserToken> : DbContextBase, IUserDbContextBase<TUser, TUserToken>
|
|
||||||
where TUser : class, IUserBase
|
|
||||||
where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
public required DbSet<TUser> Users { get; set; }
|
|
||||||
public required DbSet<TUserToken> UserTokens { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DbSets.Users;
|
|
||||||
|
|
||||||
public interface IUserDbSet<TUser> where TUser : class, IUserBase
|
|
||||||
{
|
|
||||||
DbSet<TUser> Users { get; set; }
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace AyCode.Database.DbSets.Users;
|
|
||||||
|
|
||||||
public interface IUserTokenDbSet<TUserToken> where TUserToken : class, IUserTokenBase
|
|
||||||
{
|
|
||||||
DbSet<TUserToken> UserTokens { get; set; }
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
using AyCode.Core.Helpers;
|
|
||||||
using AyCode.Database.DataLayers;
|
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
using AyCode.Interfaces.Entities;
|
|
||||||
|
|
||||||
namespace AyCode.Database.Extensions;
|
|
||||||
|
|
||||||
public static class DalExtension
|
|
||||||
{
|
|
||||||
public static Task<TResultType> SessionAsync<TDbContext, TResultType>(this IDalBase<TDbContext> dal, Func<TDbContext, TResultType> callback) where TDbContext : DbContextBase
|
|
||||||
=> TaskHelper.ToThreadPoolTask(() => dal.Session(callback));
|
|
||||||
|
|
||||||
public static Task<IEnumerable<TEntity>> SessionAsync<TDbContext, TEntity>(this IDalBase<TDbContext> dal, Func<TDbContext, IQueryable<TEntity>> callback) where TEntity : IEntity where TDbContext : DbContextBase
|
|
||||||
=> TaskHelper.ToThreadPoolTask(() => dal.Session(callback));
|
|
||||||
|
|
||||||
public static TResultType Session<TDbContext, TResultType>(this IDalBase<TDbContext> dal, Func<TDbContext, TResultType> callback) where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
using var ctx = dal.CreateDbContext();
|
|
||||||
|
|
||||||
return ctx.Session(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<TEntity> Session<TDbContext, TEntity>(this IDalBase<TDbContext> dal, Func<TDbContext, IQueryable<TEntity>> callback) where TEntity : IEntity where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
using var ctx = dal.CreateDbContext();
|
|
||||||
|
|
||||||
return ctx.Session(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Task<bool> TransactionAsync<TDbContext>(this IDalBase<TDbContext> dal, Func<TDbContext, bool> callbackTransactionBody, bool throwException = false) where TDbContext : DbContextBase
|
|
||||||
=> TaskHelper.ToThreadPoolTask(() => dal.Transaction(callbackTransactionBody, throwException));
|
|
||||||
|
|
||||||
public static bool Transaction<TDbContext>(this IDalBase<TDbContext> dal, Func<TDbContext, bool> callbackTransactionBody, bool throwException = false) where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
using var ctx = dal.CreateDbContext();
|
|
||||||
|
|
||||||
return ctx.Transaction(callbackTransactionBody, throwException);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
using AyCode.Core.Consts;
|
|
||||||
using AyCode.Core.Helpers;
|
|
||||||
using AyCode.Core.Logger;
|
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
using AyCode.Interfaces.Entities;
|
|
||||||
|
|
||||||
namespace AyCode.Database.Extensions;
|
|
||||||
|
|
||||||
public static class DbSessionExtension
|
|
||||||
{
|
|
||||||
public static Task<TResultType> SessionAsync<TDbContext, TResultType>(this TDbContext ctx, Func<TDbContext, TResultType> callback) where TDbContext : DbContextBase
|
|
||||||
=> TaskHelper.ToThreadPoolTask(() => ctx.Session(callback));
|
|
||||||
|
|
||||||
public static TResultType Session<TDbContext, TResultType>(this TDbContext ctx, Func<TDbContext, TResultType> callback) where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
TResultType result;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = callback(ctx);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var errorText = $"Session({ctx}) callback error...{AcEnv.NL}";
|
|
||||||
Logger.Error($"{errorText}", ex);
|
|
||||||
|
|
||||||
throw new Exception($"{errorText}{ex}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static IEnumerable<TEntity> Session<TDbContext, TEntity>(this TDbContext ctx, Func<TDbContext, IQueryable<TEntity>> callback)
|
|
||||||
where TEntity : IEntity
|
|
||||||
where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
foreach (var entity in callback(ctx))
|
|
||||||
yield return entity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
using AyCode.Core.Helpers;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using AyCode.Database.DbContexts;
|
|
||||||
using AyCode.Core.Logger;
|
|
||||||
using AyCode.Core.Consts;
|
|
||||||
|
|
||||||
namespace AyCode.Database.Extensions;
|
|
||||||
|
|
||||||
public static class DbTransactionExtension
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// BeginTransaction
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private static IDbContextTransaction OpenTransaction<TDbContext>(this TDbContext ctx) where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
ctx.Database.AutoTransactionBehavior = AutoTransactionBehavior.Never;
|
|
||||||
|
|
||||||
return ctx.Database.BeginTransaction(); //IDbContextTransaction
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True, ha sikeres volt a Commit.</returns>
|
|
||||||
private static bool CommitTransaction<TDbContext>(this TDbContext ctx, bool throwException = false) where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
var result = false;
|
|
||||||
var transaction = ctx.Database?.CurrentTransaction;
|
|
||||||
|
|
||||||
if (transaction == null) return false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ctx.SaveChanges();
|
|
||||||
transaction.Commit();
|
|
||||||
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var errorText = $"Transaction({ctx}) transaction ROLLBACK!{AcEnv.NL}";
|
|
||||||
|
|
||||||
transaction.Rollback();
|
|
||||||
|
|
||||||
if (throwException) throw new Exception(errorText, ex);
|
|
||||||
Logger.Error($"{errorText}", ex);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Task<bool> TransactionAsync<TDbContext>(this TDbContext ctx, Func<TDbContext, bool> callbackTransactionBody, bool throwException = false) where TDbContext : DbContextBase
|
|
||||||
=> TaskHelper.ToThreadPoolTask(() => ctx.Transaction(callbackTransactionBody, throwException));
|
|
||||||
|
|
||||||
public static bool Transaction<TDbContext>(this TDbContext ctx, Func<TDbContext, bool> callbackTransactionBody, bool throwException = false) where TDbContext : DbContextBase
|
|
||||||
{
|
|
||||||
var result = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using var transaction = ctx.OpenTransaction();
|
|
||||||
|
|
||||||
if (callbackTransactionBody(ctx)) result = ctx.CommitTransaction(throwException);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
transaction.Rollback();
|
|
||||||
Logger.Warning($"Transaction({ctx}) transaction ROLLBACK!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (throwException) throw;
|
|
||||||
|
|
||||||
result = false;
|
|
||||||
Logger.Error($"Transaction({ctx}) transaction error...{AcEnv.NL}", ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//result = ctx.CloseDbContext(false) && result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,19 +10,18 @@ using AyCode.Interfaces.Groups;
|
||||||
namespace AyCode.Entities.Groups
|
namespace AyCode.Entities.Groups
|
||||||
{
|
{
|
||||||
//[Table("Groups")]
|
//[Table("Groups")]
|
||||||
public abstract class GroupBase : IGroupBase
|
public class GroupBase : IGroupBase
|
||||||
{
|
{
|
||||||
protected GroupBase() { }
|
public GroupBase() { }
|
||||||
|
|
||||||
protected GroupBase(bool isPublic) : this(Guid.NewGuid(), isPublic) { }
|
public GroupBase(bool isPublic) : this(Guid.NewGuid(), isPublic) { }
|
||||||
|
public GroupBase(Guid id, bool isPublic) : this()
|
||||||
protected GroupBase(Guid id, bool isPublic) : this()
|
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
IsPublic = isPublic;
|
IsPublic = isPublic;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
|
//[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public bool IsPublic { get; set; }
|
public bool IsPublic { get; set; }
|
||||||
public DateTime Created { get; set; }
|
public DateTime Created { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -12,41 +12,43 @@ namespace AyCode.Entities.Users
|
||||||
[Table("Users")]
|
[Table("Users")]
|
||||||
public class UserBase : IUserBase
|
public class UserBase : IUserBase
|
||||||
{
|
{
|
||||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
[Column("Email")]
|
|
||||||
public string EmailAddress { get; set; }
|
|
||||||
//public string NormalizedEmail { get; set; }
|
|
||||||
public string PhoneNumber { get; set; }
|
|
||||||
public string Password { get; set; }
|
|
||||||
public string? RefreshToken { get; set; }
|
|
||||||
|
|
||||||
public bool EmailConfirmed { get; set; }
|
|
||||||
|
|
||||||
public DateTime Created { get; set; }
|
|
||||||
public DateTime Modified { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public UserBase() { }
|
public UserBase() { }
|
||||||
|
|
||||||
public UserBase(string email, string password) : this(Guid.NewGuid(), email, password) { }
|
public UserBase(string email, string password) : this(Guid.NewGuid(), email, password) { }
|
||||||
public UserBase(Guid id, string email, string password) : this()
|
public UserBase(Guid id, string email, string password) : this()
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
EmailAddress = email;
|
Email = email;
|
||||||
Password = password;
|
Password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserBase(string email, string phoneNumber, string password) : this(Guid.NewGuid(), email, phoneNumber, password) { }
|
public UserBase(string email, string phoneNumber, string password) : this(Guid.NewGuid(), email, phoneNumber, password) { }
|
||||||
public UserBase(Guid id, string email, string phoneNumber, string password) : this(id, email, password)
|
public UserBase(Guid id, string email, string phoneNumber, string password) : this()
|
||||||
{
|
{
|
||||||
|
Id = id;
|
||||||
|
Email = email;
|
||||||
PhoneNumber = phoneNumber;
|
PhoneNumber = phoneNumber;
|
||||||
|
Password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserBase(string email, string phoneNumber, string password, string refreshToken) : this(Guid.NewGuid(), email, phoneNumber, password, refreshToken) { }
|
public UserBase(string email, string phoneNumber, string password, string refreshToken) : this(Guid.NewGuid(), email, phoneNumber, password, refreshToken) { }
|
||||||
public UserBase(Guid id, string email, string phoneNumber, string password, string refreshToken) : this(id, email, phoneNumber, password)
|
public UserBase(Guid id, string email, string phoneNumber, string password, string refreshToken) : this()
|
||||||
{
|
{
|
||||||
|
Id = id;
|
||||||
|
Email = email;
|
||||||
|
PhoneNumber = phoneNumber;
|
||||||
|
Password = password;
|
||||||
RefreshToken = refreshToken;
|
RefreshToken = refreshToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string PhoneNumber { get; set; }
|
||||||
|
public string Password { get; set; }
|
||||||
|
public string? RefreshToken { get; set; }
|
||||||
|
|
||||||
|
public DateTime Created { get; set; }
|
||||||
|
public DateTime Modified { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
using AyCode.Interfaces.Users;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace AyCode.Entities.Users;
|
|
||||||
|
|
||||||
[Table("UserToken")]
|
|
||||||
public class UserTokenBase : IUserTokenBase
|
|
||||||
{
|
|
||||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
[Required] public Guid UserId { get; set; }
|
|
||||||
[Required] public bool IsActive { get; set; }
|
|
||||||
|
|
||||||
[Required, MaxLength(32)]
|
|
||||||
public string Token { get; set; }
|
|
||||||
public DateTime? TokenSent { get; set; }
|
|
||||||
public DateTime? TokenExpiration { get; set; }
|
|
||||||
|
|
||||||
public DateTime Created { get; set; }
|
|
||||||
public DateTime Modified { get; set; }
|
|
||||||
}
|
|
||||||
|
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace AyCode.Interfaces.Groups
|
namespace AyCode.Interfaces.Groups
|
||||||
{
|
{
|
||||||
public interface IGroupBase : IEntityGuid, ITimeStampInfo
|
public interface IGroupBase : IEntity, ITimeStampInfo
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace AyCode.Interfaces.Users;
|
|
||||||
|
|
||||||
public interface IEmailAddress
|
|
||||||
{
|
|
||||||
[MaxLength(150)]
|
|
||||||
string EmailAddress { get; set; }
|
|
||||||
|
|
||||||
bool EmailConfirmed { get; set; }
|
|
||||||
//[MaxLength(150)]
|
|
||||||
//string NormalizedEmail { get; set; }
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
namespace AyCode.Interfaces.Users;
|
|
||||||
|
|
||||||
public interface IPassword
|
|
||||||
{
|
|
||||||
string Password { get; set; }
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,8 @@ using AyCode.Interfaces.TimeStampInfo;
|
||||||
|
|
||||||
namespace AyCode.Interfaces.Users;
|
namespace AyCode.Interfaces.Users;
|
||||||
|
|
||||||
public interface IUserBase : IEntityGuid, IEmailAddress, IPassword, ITimeStampInfo
|
public interface IUserBase : IEntityGuid, ITimeStampInfo
|
||||||
{
|
{
|
||||||
public string? RefreshToken { get; set; }
|
string Email { get; }
|
||||||
|
string Password { get; }
|
||||||
}
|
}
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using AyCode.Interfaces.Entities;
|
|
||||||
using AyCode.Interfaces.TimeStampInfo;
|
|
||||||
|
|
||||||
namespace AyCode.Interfaces.Users;
|
|
||||||
|
|
||||||
public interface IUserTokenBase : IEntity<int>, ITimeStampInfo
|
|
||||||
{
|
|
||||||
public Guid UserId { get; set; }
|
|
||||||
public bool IsActive { get; set; }
|
|
||||||
|
|
||||||
public string Token { get; set; }
|
|
||||||
public DateTime? TokenSent { get; set; }
|
|
||||||
public DateTime? TokenExpiration { get; set; }
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue