Add premium access retrieval methods to IUserRepository and implementations in UserRepository classes. Introduced GetPremiumAccessByIdsAsync and GetPremiumAccessAsync methods to fetch premium status for multiple users and a single user, respectively. Updated using directives to include necessary models.

This commit is contained in:
Rui Tome 2025-12-08 16:29:47 +00:00
parent 97bcf41352
commit 0a42c9e5d7
No known key found for this signature in database
GPG Key ID: 526239D96A8EC066
3 changed files with 61 additions and 1 deletions

View File

@ -1,4 +1,5 @@
using Bit.Core.Entities;
using Bit.Core.Billing.Premium.Models;
using Bit.Core.Entities;
using Bit.Core.KeyManagement.UserKey;
using Bit.Core.Models.Data;
@ -37,6 +38,18 @@ public interface IUserRepository : IRepository<User, Guid>
[Obsolete("Use IUserService.CanAccessPremium instead. This method is only used when feature flag 'PremiumAccessQuery' is disabled.")]
Task<UserWithCalculatedPremium?> GetCalculatedPremiumAsync(Guid userId);
/// <summary>
/// Retrieves premium access status for multiple users.
/// </summary>
/// <param name="ids">The user IDs to check</param>
/// <returns>Collection of UserPremiumAccess objects containing premium status information</returns>
Task<IEnumerable<UserPremiumAccess>> GetPremiumAccessByIdsAsync(IEnumerable<Guid> ids);
/// <summary>
/// Retrieves premium access status for a single user.
/// </summary>
/// <param name="userId">The user ID to check</param>
/// <returns>UserPremiumAccess object containing premium status information, or null if user not found</returns>
Task<UserPremiumAccess?> GetPremiumAccessAsync(Guid userId);
/// <summary>
/// Sets a new user key and updates all encrypted data.
/// <para>Warning: Any user key encrypted data not included will be lost.</para>
/// </summary>

View File

@ -1,6 +1,7 @@
using System.Data;
using System.Text.Json;
using Bit.Core;
using Bit.Core.Billing.Premium.Models;
using Bit.Core.Entities;
using Bit.Core.KeyManagement.UserKey;
using Bit.Core.Models.Data;
@ -324,6 +325,25 @@ public class UserRepository : Repository<User, Guid>, IUserRepository
return result.SingleOrDefault();
}
public async Task<IEnumerable<UserPremiumAccess>> GetPremiumAccessByIdsAsync(IEnumerable<Guid> ids)
{
using (var connection = new SqlConnection(ReadOnlyConnectionString))
{
var results = await connection.QueryAsync<UserPremiumAccess>(
$"[{Schema}].[{Table}_ReadPremiumAccessByIds]",
new { Ids = ids.ToGuidIdArrayTVP() },
commandType: CommandType.StoredProcedure);
return results.ToList();
}
}
public async Task<UserPremiumAccess?> GetPremiumAccessAsync(Guid userId)
{
var result = await GetPremiumAccessByIdsAsync([userId]);
return result.SingleOrDefault();
}
private async Task ProtectDataAndSaveAsync(User user, Func<Task> saveTask)
{
if (user == null)

View File

@ -1,4 +1,5 @@
using AutoMapper;
using Bit.Core.Billing.Premium.Models;
using Bit.Core.KeyManagement.UserKey;
using Bit.Core.Models.Data;
using Bit.Core.Repositories;
@ -275,6 +276,32 @@ public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserR
return result.FirstOrDefault();
}
public async Task<IEnumerable<UserPremiumAccess>> GetPremiumAccessByIdsAsync(IEnumerable<Guid> ids)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var users = dbContext.Users.Where(x => ids.Contains(x.Id));
return await users.Select(user => new UserPremiumAccess
{
Id = user.Id,
PersonalPremium = user.Premium,
OrganizationPremium = dbContext.OrganizationUsers
.Any(ou => ou.UserId == user.Id &&
dbContext.Organizations
.Any(o => o.Id == ou.OrganizationId &&
o.Enabled == true &&
o.UsersGetPremium == true))
}).ToListAsync();
}
}
public async Task<UserPremiumAccess?> GetPremiumAccessAsync(Guid userId)
{
var result = await GetPremiumAccessByIdsAsync([userId]);
return result.FirstOrDefault();
}
public override async Task DeleteAsync(Core.Entities.User user)
{
using (var scope = ServiceScopeFactory.CreateScope())