chore(premium): [PM-29186] Remove 2FA user interface from premium method signatures

* Removed 2FA user interface from premium method signatures

* Added some more comments for clarity and small touchups.

* Suggested documentation updates.

---------

Co-authored-by: Patrick Pimentel <ppimentel@bitwarden.com>
This commit is contained in:
Todd Martin 2025-12-08 17:54:55 -05:00 committed by GitHub
parent acc2529353
commit b5f7f9f6a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 27 additions and 23 deletions

View File

@ -63,11 +63,6 @@ public class OrganizationUserUserDetails : IExternal, ITwoFactorProvidersUser, I
return UserId;
}
public bool GetPremium()
{
return Premium.GetValueOrDefault(false);
}
public Permissions GetPermissions()
{
return string.IsNullOrWhiteSpace(Permissions) ? null

View File

@ -1,14 +1,14 @@
// FIXME: Update this file to be null safe and then delete the line below
#nullable disable
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Enums;
using Bit.Core.Services;
namespace Bit.Core.Auth.Models;
/// <summary>
/// An interface representing a user entity that supports two-factor providers
/// </summary>
public interface ITwoFactorProvidersUser
{
string TwoFactorProviders { get; }
string? TwoFactorProviders { get; }
/// <summary>
/// Get the two factor providers for the user. Currently it can be assumed providers are enabled
/// if they exists in the dictionary. When two factor providers are disabled they are removed
@ -16,7 +16,10 @@ public interface ITwoFactorProvidersUser
/// <see cref="IOrganizationService.DisableTwoFactorProviderAsync"/>
/// </summary>
/// <returns>Dictionary of providers with the type enum as the key</returns>
Dictionary<TwoFactorProviderType, TwoFactorProvider> GetTwoFactorProviders();
Dictionary<TwoFactorProviderType, TwoFactorProvider>? GetTwoFactorProviders();
/// <summary>
/// The unique `UserId` of the user entity for which there are two-factor providers configured.
/// </summary>
/// <returns>The unique identifier for the user</returns>
Guid? GetUserId();
bool GetPremium();
}

View File

@ -200,11 +200,6 @@ public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFac
return Id;
}
public bool GetPremium()
{
return Premium;
}
public int GetSecurityVersion()
{
// If no security version is set, it is version 1. The minimum initialized version is 2.

View File

@ -4,7 +4,6 @@
using System.Security.Claims;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Models;
using Bit.Core.Billing.Models.Business;
using Bit.Core.Entities;
using Bit.Core.Enums;
@ -60,11 +59,22 @@ public interface IUserService
Task<bool> CheckPasswordAsync(User user, string password);
/// <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.
/// </summary>
/// <param name="user">user being acted on</param>
/// <returns>true if they can access premium; false otherwise.</returns>
Task<bool> CanAccessPremium(ITwoFactorProvidersUser user);
Task<bool> HasPremiumFromOrganization(ITwoFactorProvidersUser user);
Task<bool> CanAccessPremium(User user);
/// <summary>
/// Checks if the user has inherited access to premium features through an organization.
///
/// This primarily serves as a means to communicate to the client when a user has inherited their premium status
/// through an organization. Feature gating logic probably should not be behind this check.
/// </summary>
/// <param name="user">user being acted on</param>
/// <returns>true if they can access premium because of organization membership; false otherwise.</returns>
Task<bool> HasPremiumFromOrganization(User user);
Task<string> GenerateSignInTokenAsync(User user, string purpose);
Task<IdentityResult> UpdatePasswordHash(User user, string newPassword,

View File

@ -1104,7 +1104,7 @@ public class UserService : UserManager<User>, IUserService
return success;
}
public async Task<bool> CanAccessPremium(ITwoFactorProvidersUser user)
public async Task<bool> CanAccessPremium(User user)
{
var userId = user.GetUserId();
if (!userId.HasValue)
@ -1112,10 +1112,10 @@ public class UserService : UserManager<User>, IUserService
return false;
}
return user.GetPremium() || await this.HasPremiumFromOrganization(user);
return user.Premium || await HasPremiumFromOrganization(user);
}
public async Task<bool> HasPremiumFromOrganization(ITwoFactorProvidersUser user)
public async Task<bool> HasPremiumFromOrganization(User user)
{
var userId = user.GetUserId();
if (!userId.HasValue)
@ -1138,6 +1138,7 @@ public class UserService : UserManager<User>, IUserService
orgAbility.UsersGetPremium &&
orgAbility.Enabled);
}
public async Task<string> GenerateSignInTokenAsync(User user, string purpose)
{
var token = await GenerateUserTokenAsync(user, Options.Tokens.PasswordResetTokenProvider,