diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityErrorCodes.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityErrorCodes.cs index ff808d9fbb..4e681c3ea1 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityErrorCodes.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityErrorCodes.cs @@ -10,4 +10,5 @@ public static class IdentityErrorCodes public const string StaticRoleDeletion = "Volo.Abp.Identity:010006"; public const string UsersCanNotChangeTwoFactor = "Volo.Abp.Identity:010007"; public const string CanNotChangeTwoFactor = "Volo.Abp.Identity:010008"; + public const string YouCannotDelegateYourself = "Volo.Abp.Identity:010009"; } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserDelegationRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserDelegationRepository.cs index c60b998b64..f880e7264f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserDelegationRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserDelegationRepository.cs @@ -13,8 +13,11 @@ public interface IIdentityUserDelegationRepository: IBasicRepository FindAsync( + Task> GetActiveDelegationsAsync( Guid sourceUserId, - Guid targetUserId, + CancellationToken cancellationToken = default); + + Task FindActiveDelegationByIdAsync( + Guid id, CancellationToken cancellationToken = default); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserDelegationManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserDelegationManager.cs index 4d08385835..14e91111d6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserDelegationManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserDelegationManager.cs @@ -19,6 +19,35 @@ public class IdentityUserDelegationManager : DomainService { return await IdentityUserDelegationRepository.GetListAsync(sourceUserId, targetUserId, cancellationToken: cancellationToken); } + + public virtual async Task> GetActiveDelegationsAsync(Guid sourceUserId, CancellationToken cancellationToken = default) + { + return await IdentityUserDelegationRepository.GetActiveDelegationsAsync(sourceUserId, cancellationToken: cancellationToken); + } + + public virtual async Task FindActiveDelegationByIdAsync(Guid id, CancellationToken cancellationToken = default) + { + return await IdentityUserDelegationRepository.FindActiveDelegationByIdAsync(id, cancellationToken: cancellationToken); + } + + public virtual async Task DelegateNewUserAsync(Guid sourceUserId, IdentityUser targetUser, DateTime startTime, DateTime endTime, CancellationToken cancellationToken = default) + { + if (sourceUserId == targetUser.Id) + { + throw new BusinessException(IdentityErrorCodes.YouCannotDelegateYourself); + } + + await IdentityUserDelegationRepository.InsertAsync( + new IdentityUserDelegation( + GuidGenerator.Create(), + sourceUserId, + targetUser.Id, + startTime, + endTime + ), + cancellationToken: cancellationToken + ); + } public virtual async Task DeleteDelegationAsync(Guid id, Guid sourceUserId, CancellationToken cancellationToken = default) { @@ -30,11 +59,6 @@ public class IdentityUserDelegationManager : DomainService } } - public virtual async Task IsDelegatedAsync(Guid sourceUserId, Guid targetUserId, CancellationToken cancellationToken = default) - { - return await IdentityUserDelegationRepository.FindAsync(sourceUserId, targetUserId, cancellationToken: cancellationToken) != null; - } - public virtual Task IsExpiredAsync(IdentityUserDelegation userDelegation) { return Task.FromResult(userDelegation.EndTime <= Clock.Now); diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserDelegationRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserDelegationRepository.cs index 4f455c2d68..1e28b68e80 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserDelegationRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserDelegationRepository.cs @@ -6,14 +6,18 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Timing; namespace Volo.Abp.Identity.EntityFrameworkCore; public class EfCoreIdentityUserDelegationRepository : EfCoreRepository, IIdentityUserDelegationRepository { - public EfCoreIdentityUserDelegationRepository(IDbContextProvider dbContextProvider) + protected IClock Clock { get; } + + public EfCoreIdentityUserDelegationRepository(IDbContextProvider dbContextProvider, IClock clock) : base(dbContextProvider) { + Clock = clock; } public async Task> GetListAsync(Guid? sourceUserId, Guid? targetUserId, CancellationToken cancellationToken = default) @@ -25,13 +29,24 @@ public class EfCoreIdentityUserDelegationRepository : EfCoreRepository FindAsync(Guid sourceUserId, Guid targetUserId, CancellationToken cancellationToken = default) + public async Task> GetActiveDelegationsAsync(Guid sourceUserId, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .AsNoTracking() + .Where(x => x.SourceUserId == sourceUserId && + x.StartTime <= Clock.Now && + x.EndTime >= Clock.Now) + .ToListAsync(cancellationToken: cancellationToken); + } + + public async Task FindActiveDelegationByIdAsync(Guid id, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()) .AsNoTracking() .FirstOrDefaultAsync(x => - x.SourceUserId == sourceUserId && - x.TargetUserId == targetUserId + x.Id == id && + x.StartTime <= Clock.Now && + x.EndTime >= Clock.Now , cancellationToken: GetCancellationToken(cancellationToken)); } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs index 7520b12e26..f85f72e84e 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs @@ -276,11 +276,6 @@ public static class IdentityDbContextModelBuilderExtensions b.ConfigureByConvention(); - b.HasIndex(x => new { - x.SourceUserId, - x.TargetUserId, - }).IsUnique(); - b.ApplyObjectExtensionMappings(); }); diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserDelegationRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserDelegationRepository.cs index ac9ac753e6..37cfc52e9c 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserDelegationRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserDelegationRepository.cs @@ -7,14 +7,18 @@ using MongoDB.Driver; using MongoDB.Driver.Linq; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; +using Volo.Abp.Timing; namespace Volo.Abp.Identity.MongoDB; public class MongoIdentityUserDelegationRepository : MongoDbRepository, IIdentityUserDelegationRepository { - public MongoIdentityUserDelegationRepository(IMongoDbContextProvider dbContextProvider) + protected IClock Clock { get; } + + public MongoIdentityUserDelegationRepository(IMongoDbContextProvider dbContextProvider, IClock clock) : base(dbContextProvider) { + Clock = clock; } public async Task> GetListAsync(Guid? sourceUserId, Guid? targetUserId, @@ -27,12 +31,22 @@ public class MongoIdentityUserDelegationRepository : MongoDbRepository FindAsync(Guid sourceUserId, Guid targetUserId, CancellationToken cancellationToken = default) + public async Task> GetActiveDelegationsAsync(Guid sourceUserId, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(cancellationToken)) + .Where(x => x.SourceUserId == sourceUserId) + .Where(x => x.StartTime <= Clock.Now && x.EndTime >= Clock.Now) + .As>() + .ToListAsync(cancellationToken: cancellationToken); + } + + public async Task FindActiveDelegationByIdAsync(Guid id, CancellationToken cancellationToken = default) { return await (await GetMongoQueryableAsync(cancellationToken)) .FirstOrDefaultAsync(x => - x.SourceUserId == sourceUserId && - x.TargetUserId == targetUserId + x.Id == id && + x.StartTime <= Clock.Now && + x.EndTime >= Clock.Now , cancellationToken: GetCancellationToken(cancellationToken)); } }