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,