using AutoMapper; using AutoMapper.QueryableExtensions; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Data; using Bit.Core.Repositories; using Bit.Infrastructure.EntityFramework.Auth.Models; using Bit.Infrastructure.EntityFramework.Repositories; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; #nullable enable namespace Bit.Infrastructure.EntityFramework.Auth.Repositories; public class AuthRequestRepository : Repository, IAuthRequestRepository { public AuthRequestRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) : base(serviceScopeFactory, mapper, (DatabaseContext context) => context.AuthRequests) { } public async Task DeleteExpiredAsync( TimeSpan userRequestExpiration, TimeSpan adminRequestExpiration, TimeSpan afterAdminApprovalExpiration) { using (var scope = ServiceScopeFactory.CreateScope()) { var dbContext = GetDatabaseContext(scope); var expiredRequests = await dbContext.AuthRequests .Where(a => (a.Type != AuthRequestType.AdminApproval && a.CreationDate.AddSeconds(userRequestExpiration.TotalSeconds) < DateTime.UtcNow) || (a.Type == AuthRequestType.AdminApproval && a.Approved != true && a.CreationDate.AddSeconds(adminRequestExpiration.TotalSeconds) < DateTime.UtcNow) || (a.Type == AuthRequestType.AdminApproval && a.Approved == true && a.ResponseDate!.Value.AddSeconds(afterAdminApprovalExpiration.TotalSeconds) < DateTime.UtcNow)) .ToListAsync(); dbContext.AuthRequests.RemoveRange(expiredRequests); return await dbContext.SaveChangesAsync(); } } public async Task> GetManyByUserIdAsync(Guid userId) { using (var scope = ServiceScopeFactory.CreateScope()) { var dbContext = GetDatabaseContext(scope); var userAuthRequests = await dbContext.AuthRequests.Where(a => a.UserId.Equals(userId)).ToListAsync(); return Mapper.Map>(userAuthRequests); } } public async Task> GetManyPendingByOrganizationIdAsync(Guid organizationId) { using (var scope = ServiceScopeFactory.CreateScope()) { var dbContext = GetDatabaseContext(scope); var orgUserAuthRequests = await (from ar in dbContext.AuthRequests where ar.OrganizationId.Equals(organizationId) && ar.ResponseDate == null && ar.Type == AuthRequestType.AdminApproval select ar).ProjectTo(Mapper.ConfigurationProvider).ToListAsync(); return orgUserAuthRequests; } } public async Task> GetManyAdminApprovalRequestsByManyIdsAsync( Guid organizationId, IEnumerable ids) { using (var scope = ServiceScopeFactory.CreateScope()) { var dbContext = GetDatabaseContext(scope); var orgUserAuthRequests = await (from ar in dbContext.AuthRequests where ar.OrganizationId.Equals(organizationId) && ids.Contains(ar.Id) && ar.Type == AuthRequestType.AdminApproval select ar).ProjectTo(Mapper.ConfigurationProvider).ToListAsync(); return orgUserAuthRequests; } } public async Task UpdateManyAsync(IEnumerable authRequests) { if (!authRequests.Any()) { return; } var entities = new List(); foreach (var authRequest in authRequests) { if (!authRequest.Id.Equals(default)) { var entity = Mapper.Map(authRequest); entities.Add(entity); } } using (var scope = ServiceScopeFactory.CreateScope()) { var dbContext = GetDatabaseContext(scope); dbContext.UpdateRange(entities); await dbContext.SaveChangesAsync(); } } }