From b5f7f9f6a08549a852d2620d0bc93f9a1c6e7e72 Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Mon, 8 Dec 2025 17:54:55 -0500 Subject: [PATCH] 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 --- .../OrganizationUserUserDetails.cs | 5 ----- src/Core/Auth/Models/ITwoFactorProvidersUser.cs | 17 ++++++++++------- src/Core/Entities/User.cs | 5 ----- src/Core/Services/IUserService.cs | 16 +++++++++++++--- .../Services/Implementations/UserService.cs | 7 ++++--- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserUserDetails.cs b/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserUserDetails.cs index 6d182e197f..00bac01f76 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserUserDetails.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserUserDetails.cs @@ -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 diff --git a/src/Core/Auth/Models/ITwoFactorProvidersUser.cs b/src/Core/Auth/Models/ITwoFactorProvidersUser.cs index 5cf137b76f..816d460572 100644 --- a/src/Core/Auth/Models/ITwoFactorProvidersUser.cs +++ b/src/Core/Auth/Models/ITwoFactorProvidersUser.cs @@ -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; +/// +/// An interface representing a user entity that supports two-factor providers +/// public interface ITwoFactorProvidersUser { - string TwoFactorProviders { get; } + string? TwoFactorProviders { get; } /// /// 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 /// /// /// Dictionary of providers with the type enum as the key - Dictionary GetTwoFactorProviders(); + Dictionary? GetTwoFactorProviders(); + /// + /// The unique `UserId` of the user entity for which there are two-factor providers configured. + /// + /// The unique identifier for the user Guid? GetUserId(); - bool GetPremium(); } diff --git a/src/Core/Entities/User.cs b/src/Core/Entities/User.cs index fec9b80d8e..1ca6606779 100644 --- a/src/Core/Entities/User.cs +++ b/src/Core/Entities/User.cs @@ -200,11 +200,6 @@ public class User : ITableObject, 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. diff --git a/src/Core/Services/IUserService.cs b/src/Core/Services/IUserService.cs index 412f9db36e..0506e08cfc 100644 --- a/src/Core/Services/IUserService.cs +++ b/src/Core/Services/IUserService.cs @@ -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 CheckPasswordAsync(User user, string password); /// /// 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. /// /// user being acted on /// true if they can access premium; false otherwise. - Task CanAccessPremium(ITwoFactorProvidersUser user); - Task HasPremiumFromOrganization(ITwoFactorProvidersUser user); + Task CanAccessPremium(User user); + + /// + /// 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. + /// + /// user being acted on + /// true if they can access premium because of organization membership; false otherwise. + Task HasPremiumFromOrganization(User user); Task GenerateSignInTokenAsync(User user, string purpose); Task UpdatePasswordHash(User user, string newPassword, diff --git a/src/Core/Services/Implementations/UserService.cs b/src/Core/Services/Implementations/UserService.cs index 57b69deb71..2d2a9f0ae7 100644 --- a/src/Core/Services/Implementations/UserService.cs +++ b/src/Core/Services/Implementations/UserService.cs @@ -1104,7 +1104,7 @@ public class UserService : UserManager, IUserService return success; } - public async Task CanAccessPremium(ITwoFactorProvidersUser user) + public async Task CanAccessPremium(User user) { var userId = user.GetUserId(); if (!userId.HasValue) @@ -1112,10 +1112,10 @@ public class UserService : UserManager, IUserService return false; } - return user.GetPremium() || await this.HasPremiumFromOrganization(user); + return user.Premium || await HasPremiumFromOrganization(user); } - public async Task HasPremiumFromOrganization(ITwoFactorProvidersUser user) + public async Task HasPremiumFromOrganization(User user) { var userId = user.GetUserId(); if (!userId.HasValue) @@ -1138,6 +1138,7 @@ public class UserService : UserManager, IUserService orgAbility.UsersGetPremium && orgAbility.Enabled); } + public async Task GenerateSignInTokenAsync(User user, string purpose) { var token = await GenerateUserTokenAsync(user, Options.Tokens.PasswordResetTokenProvider,