mirror of
https://github.com/bitwarden/server
synced 2025-12-25 04:33:26 +00:00
[AC-1698] Check if a user has 2FA enabled more efficiently (#4524)
* feat: Add stored procedure for reading organization user details with premium access by organization ID The code changes include: - Addition of a new stored procedure [dbo].[OrganizationUserUserDetailsWithPremiumAccess_ReadByOrganizationId] to read organization user details with premium access by organization ID - Modification of the IUserService interface to include an optional parameter for checking two-factor authentication with premium access - Modification of the UserService class to handle the new optional parameter in the TwoFactorIsEnabledAsync method - Addition of a new method GetManyDetailsWithPremiumAccessByOrganizationAsync in the IOrganizationUserRepository interface to retrieve organization user details with premium access by organization ID - Addition of a new view [dbo].[OrganizationUserUserDetailsWithPremiumAccessView] to retrieve organization user details with premium access * Add IUserRepository.SearchDetailsAsync that includes the field HasPremiumAccess * Check the feature flag on Admin.UsersController to see if the optimization runs * Modify PolicyService to run query optimization if the feature flag is enabled * Refactor the parameter check on UserService.TwoFactorIsEnabledAsync * Run query optimization on public MembersController if feature flag is enabled * Restore refactor * Reverted change used for development * Add unit tests for OrganizationService.RestoreUser * Separate new CheckPoliciesBeforeRestoreAsync optimization into new method * Add more unit tests * Apply refactor to bulk restore * Add GetManyDetailsAsync method to IUserRepository. Add ConfirmUsersAsync_vNext method to IOrganizationService * Add unit tests for ConfirmUser_vNext * Refactor the optimization to use the new TwoFactorIsEnabledAsync method instead of changing the existing one * Removed unused sql scripts and added migration script * Remove unnecessary view * chore: Remove unused SearchDetailsAsync method from IUserRepository and UserRepository * refactor: Use UserDetails constructor in UserRepository * Add summary to IUserRepository.GetManyDetailsAsync * Add summary descriptions to IUserService.TwoFactorIsEnabledAsync * Remove obsolete annotation from IUserRepository.UpdateUserKeyAndEncryptedDataAsync * refactor: Rename UserDetails to UserWithCalculatedPremium across the codebase * Extract IUserService.TwoFactorIsEnabledAsync into a new TwoFactorIsEnabledQuery class * Add unit tests for TwoFactorIsEnabledQuery * Update TwoFactorIsEnabledQueryTests to include additional provider types * Refactor TwoFactorIsEnabledQuery * Refactor TwoFactorIsEnabledQuery and update tests * refactor: Update TwoFactorIsEnabledQueryTests to include test for null TwoFactorProviders * refactor: Improve TwoFactorIsEnabledQuery and update tests * refactor: Improve TwoFactorIsEnabledQuery and update tests * Remove empty <returns> from summary * Update User_ReadByIdsWithCalculatedPremium stored procedure to accept JSON array of IDs
This commit is contained in:
62
src/Core/Models/Data/UserWithCalculatedPremium.cs
Normal file
62
src/Core/Models/Data/UserWithCalculatedPremium.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Core.Models.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a user with an additional property indicating if the user has premium access.
|
||||
/// </summary>
|
||||
public class UserWithCalculatedPremium : User
|
||||
{
|
||||
public UserWithCalculatedPremium() { }
|
||||
|
||||
public UserWithCalculatedPremium(User user)
|
||||
{
|
||||
Id = user.Id;
|
||||
Name = user.Name;
|
||||
Email = user.Email;
|
||||
EmailVerified = user.EmailVerified;
|
||||
MasterPassword = user.MasterPassword;
|
||||
MasterPasswordHint = user.MasterPasswordHint;
|
||||
Culture = user.Culture;
|
||||
SecurityStamp = user.SecurityStamp;
|
||||
TwoFactorProviders = user.TwoFactorProviders;
|
||||
TwoFactorRecoveryCode = user.TwoFactorRecoveryCode;
|
||||
EquivalentDomains = user.EquivalentDomains;
|
||||
ExcludedGlobalEquivalentDomains = user.ExcludedGlobalEquivalentDomains;
|
||||
AccountRevisionDate = user.AccountRevisionDate;
|
||||
Key = user.Key;
|
||||
PublicKey = user.PublicKey;
|
||||
PrivateKey = user.PrivateKey;
|
||||
Premium = user.Premium;
|
||||
PremiumExpirationDate = user.PremiumExpirationDate;
|
||||
RenewalReminderDate = user.RenewalReminderDate;
|
||||
Storage = user.Storage;
|
||||
MaxStorageGb = user.MaxStorageGb;
|
||||
Gateway = user.Gateway;
|
||||
GatewayCustomerId = user.GatewayCustomerId;
|
||||
GatewaySubscriptionId = user.GatewaySubscriptionId;
|
||||
ReferenceData = user.ReferenceData;
|
||||
LicenseKey = user.LicenseKey;
|
||||
ApiKey = user.ApiKey;
|
||||
Kdf = user.Kdf;
|
||||
KdfIterations = user.KdfIterations;
|
||||
KdfMemory = user.KdfMemory;
|
||||
KdfParallelism = user.KdfParallelism;
|
||||
CreationDate = user.CreationDate;
|
||||
RevisionDate = user.RevisionDate;
|
||||
ForcePasswordReset = user.ForcePasswordReset;
|
||||
UsesKeyConnector = user.UsesKeyConnector;
|
||||
FailedLoginCount = user.FailedLoginCount;
|
||||
LastFailedLoginDate = user.LastFailedLoginDate;
|
||||
AvatarColor = user.AvatarColor;
|
||||
LastPasswordChangeDate = user.LastPasswordChangeDate;
|
||||
LastKdfChangeDate = user.LastKdfChangeDate;
|
||||
LastKeyRotationDate = user.LastKeyRotationDate;
|
||||
LastEmailChangeDate = user.LastEmailChangeDate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the user has premium access, either individually or through an organization.
|
||||
/// </summary>
|
||||
public bool HasPremiumAccess { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user