Refactor IUserService to enhance premium access checks

* Updated CanAccessPremium and HasPremiumFromOrganization methods to clarify usage with the new premium access query.
* Integrated IHasPremiumAccessQuery into UserService for improved premium access handling based on feature flag.
* Adjusted method documentation to reflect changes in premium access logic.
This commit is contained in:
Rui Tome 2025-12-09 14:07:35 +00:00
parent 2f11c1384c
commit 9a68a972ca
No known key found for this signature in database
GPG Key ID: 526239D96A8EC066
2 changed files with 17 additions and 4 deletions

View File

@ -60,11 +60,10 @@ public interface IUserService
/// <summary>
/// Checks if the user has access to premium features, either through a personal subscription or through an organization.
///
/// This is the preferred way to definitively know if a user has access to premium features.
/// This is the preferred way to definitively know if a user has access to premium features when you already have the User object.
/// </summary>
/// <param name="user">user being acted on</param>
/// <returns>true if they can access premium; false otherwise.</returns>
[Obsolete("Use IHasPremiumAccessQuery.HasPremiumAccessAsync instead. This method is only used when feature flag 'PremiumAccessQuery' is disabled.")]
Task<bool> CanAccessPremium(User user);
/// <summary>
@ -75,7 +74,7 @@ public interface IUserService
/// </summary>
/// <param name="user">user being acted on</param>
/// <returns>true if they can access premium because of organization membership; false otherwise.</returns>
[Obsolete("Use IHasPremiumAccessQuery.HasPremiumFromOrganizationAsync instead. This method is only used when feature flag 'PremiumAccessQuery' is disabled.")]
[Obsolete("Use IHasPremiumAccessQuery.HasPremiumFromOrganizationAsync instead. Redirects to new query when feature flag 'PremiumAccessQuery' is enabled.")]
Task<bool> HasPremiumFromOrganization(User user);
Task<string> GenerateSignInTokenAsync(User user, string purpose);

View File

@ -17,6 +17,7 @@ using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
using Bit.Core.Billing.Models;
using Bit.Core.Billing.Models.Business;
using Bit.Core.Billing.Models.Sales;
using Bit.Core.Billing.Premium.Queries;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Billing.Tax.Models;
@ -73,6 +74,7 @@ public class UserService : UserManager<User>, IUserService
private readonly IDistributedCache _distributedCache;
private readonly IPolicyRequirementQuery _policyRequirementQuery;
private readonly IPricingClient _pricingClient;
private readonly IHasPremiumAccessQuery _hasPremiumAccessQuery;
public UserService(
IUserRepository userRepository,
@ -108,7 +110,8 @@ public class UserService : UserManager<User>, IUserService
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
IDistributedCache distributedCache,
IPolicyRequirementQuery policyRequirementQuery,
IPricingClient pricingClient)
IPricingClient pricingClient,
IHasPremiumAccessQuery hasPremiumAccessQuery)
: base(
store,
optionsAccessor,
@ -149,6 +152,7 @@ public class UserService : UserManager<User>, IUserService
_distributedCache = distributedCache;
_policyRequirementQuery = policyRequirementQuery;
_pricingClient = pricingClient;
_hasPremiumAccessQuery = hasPremiumAccessQuery;
}
public Guid? GetProperUserId(ClaimsPrincipal principal)
@ -1112,6 +1116,11 @@ public class UserService : UserManager<User>, IUserService
return false;
}
if (_featureService.IsEnabled(FeatureFlagKeys.PremiumAccessQuery))
{
return user.Premium || await _hasPremiumAccessQuery.HasPremiumFromOrganizationAsync(userId.Value);
}
return user.Premium || await HasPremiumFromOrganization(user);
}
@ -1123,6 +1132,11 @@ public class UserService : UserManager<User>, IUserService
return false;
}
if (_featureService.IsEnabled(FeatureFlagKeys.PremiumAccessQuery))
{
return await _hasPremiumAccessQuery.HasPremiumFromOrganizationAsync(userId.Value);
}
// orgUsers in the Invited status are not associated with a userId yet, so this will get
// orgUsers in Accepted and Confirmed states only
var orgUsers = await _organizationUserRepository.GetManyByUserAsync(userId.Value);