mirror of
https://github.com/bitwarden/server.git
synced 2024-11-21 12:05:42 +01:00
[PM-1033] refactor: UpdateUserResetPasswordEnrollmentCommand
This commit is contained in:
parent
dc503b3035
commit
43df689c7f
@ -8,6 +8,8 @@ using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationUsers;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@ -27,6 +29,7 @@ public class OrganizationUsersController : Controller
|
||||
private readonly IUserService _userService;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly IUpdateUserResetPasswordEnrollmentCommand _updateUserResetPasswordEnrollmentCommand;
|
||||
|
||||
public OrganizationUsersController(
|
||||
IOrganizationRepository organizationRepository,
|
||||
@ -36,6 +39,7 @@ public class OrganizationUsersController : Controller
|
||||
IGroupRepository groupRepository,
|
||||
IUserService userService,
|
||||
IPolicyRepository policyRepository,
|
||||
IUpdateUserResetPasswordEnrollmentCommand updateUserResetPasswordEnrollmentCommand,
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
@ -45,6 +49,7 @@ public class OrganizationUsersController : Controller
|
||||
_groupRepository = groupRepository;
|
||||
_userService = userService;
|
||||
_policyRepository = policyRepository;
|
||||
_updateUserResetPasswordEnrollmentCommand = updateUserResetPasswordEnrollmentCommand;
|
||||
_currentContext = currentContext;
|
||||
}
|
||||
|
||||
@ -213,7 +218,7 @@ public class OrganizationUsersController : Controller
|
||||
|
||||
if (useMasterPasswordPolicy)
|
||||
{
|
||||
await _organizationService.UpdateUserResetPasswordEnrollmentAsync(orgId, user.Id, model.ResetPasswordKey, _userService, user.Id);
|
||||
await _updateUserResetPasswordEnrollmentCommand.UpdateAsync(orgId, user.Id, model.ResetPasswordKey, user.Id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,8 +319,14 @@ public class OrganizationUsersController : Controller
|
||||
}
|
||||
|
||||
var callingUserId = user.Id;
|
||||
await _organizationService.UpdateUserResetPasswordEnrollmentAsync(
|
||||
new Guid(orgId), new Guid(userId), model.ResetPasswordKey, _userService, callingUserId);
|
||||
await _updateUserResetPasswordEnrollmentCommand.UpdateAsync(
|
||||
new Guid(orgId), new Guid(userId), model.ResetPasswordKey, callingUserId);
|
||||
|
||||
//if (orgUser.Status == OrganizationUserStatusType.Invited)
|
||||
//{
|
||||
// var user = await _userRepository.GetByIdAsync(userId);
|
||||
// await _organizationService.AcceptUserAsync(orgUser, user, _userService);
|
||||
//}
|
||||
}
|
||||
|
||||
[HttpPut("{id}/reset-password")]
|
||||
|
@ -15,6 +15,8 @@ using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterpri
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Cloud;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.SelfHosted;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationUsers;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Tokens;
|
||||
@ -38,6 +40,7 @@ public static class OrganizationServiceCollectionExtensions
|
||||
services.AddOrganizationGroupCommands();
|
||||
services.AddOrganizationLicenseCommandsQueries();
|
||||
services.AddOrganizationDomainCommandsQueries();
|
||||
services.AddOrganizationUserCommandsQueries();
|
||||
}
|
||||
|
||||
private static void AddOrganizationConnectionCommands(this IServiceCollection services)
|
||||
@ -107,6 +110,11 @@ public static class OrganizationServiceCollectionExtensions
|
||||
services.AddScoped<IDeleteOrganizationDomainCommand, DeleteOrganizationDomainCommand>();
|
||||
}
|
||||
|
||||
private static void AddOrganizationUserCommandsQueries(this IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IUpdateUserResetPasswordEnrollmentCommand, UpdateUserResetPasswordEnrollmentCommand>();
|
||||
}
|
||||
|
||||
private static void AddTokenizers(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IDataProtectorTokenFactory<OrganizationSponsorshipOfferTokenable>>(serviceProvider =>
|
||||
|
@ -0,0 +1,7 @@
|
||||
namespace Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
|
||||
public interface IUpdateUserResetPasswordEnrollmentCommand
|
||||
{
|
||||
Task UpdateAsync(Guid organizationId, Guid userId, string resetPasswordKey, Guid? callingUserId);
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.OrganizationFeatures.OrganizationUsers;
|
||||
|
||||
public class UpdateUserResetPasswordEnrollmentCommand : IUpdateUserResetPasswordEnrollmentCommand
|
||||
{
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IEventService _eventService;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
|
||||
public UpdateUserResetPasswordEnrollmentCommand(
|
||||
IOrganizationRepository organizationRepository,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IEventService eventService,
|
||||
IPolicyRepository policyRepository)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
_eventService = eventService;
|
||||
_policyRepository = policyRepository;
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(Guid organizationId, Guid userId, string resetPasswordKey, Guid? callingUserId)
|
||||
{
|
||||
// Org User must be the same as the calling user and the organization ID associated with the user must match passed org ID
|
||||
var orgUser = await _organizationUserRepository.GetByOrganizationAsync(organizationId, userId);
|
||||
if (!callingUserId.HasValue || orgUser == null || orgUser.UserId != callingUserId.Value ||
|
||||
orgUser.OrganizationId != organizationId)
|
||||
{
|
||||
throw new BadRequestException("User not valid.");
|
||||
}
|
||||
|
||||
// Make sure the organization has the ability to use password reset
|
||||
var org = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
if (org == null || !org.UseResetPassword)
|
||||
{
|
||||
throw new BadRequestException("Organization does not allow password reset enrollment.");
|
||||
}
|
||||
|
||||
// Make sure the organization has the policy enabled
|
||||
var resetPasswordPolicy =
|
||||
await _policyRepository.GetByOrganizationIdTypeAsync(organizationId, PolicyType.ResetPassword);
|
||||
if (resetPasswordPolicy == null || !resetPasswordPolicy.Enabled)
|
||||
{
|
||||
throw new BadRequestException("Organization does not have the password reset policy enabled.");
|
||||
}
|
||||
|
||||
// Block the user from withdrawal if auto enrollment is enabled
|
||||
if (resetPasswordKey == null && resetPasswordPolicy.Data != null)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<ResetPasswordDataModel>(resetPasswordPolicy.Data, JsonHelpers.IgnoreCase);
|
||||
|
||||
if (data?.AutoEnrollEnabled ?? false)
|
||||
{
|
||||
throw new BadRequestException("Due to an Enterprise Policy, you are not allowed to withdraw from Password Reset.");
|
||||
}
|
||||
}
|
||||
|
||||
orgUser.ResetPasswordKey = resetPasswordKey;
|
||||
await _organizationUserRepository.ReplaceAsync(orgUser);
|
||||
await _eventService.LogOrganizationUserEventAsync(orgUser, resetPasswordKey != null ?
|
||||
EventType.OrganizationUser_ResetPassword_Enroll : EventType.OrganizationUser_ResetPassword_Withdraw);
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,6 @@ public interface IOrganizationService
|
||||
Task<List<Tuple<OrganizationUser, string>>> DeleteUsersAsync(Guid organizationId,
|
||||
IEnumerable<Guid> organizationUserIds, Guid? deletingUserId);
|
||||
Task UpdateUserGroupsAsync(OrganizationUser organizationUser, IEnumerable<Guid> groupIds, Guid? loggedInUserId);
|
||||
Task UpdateUserResetPasswordEnrollmentAsync(Guid organizationId, Guid userId, string resetPasswordKey, IUserService userService, Guid? callingUserId);
|
||||
Task ImportAsync(Guid organizationId, Guid? importingUserId, IEnumerable<ImportedGroup> groups,
|
||||
IEnumerable<ImportedOrganizationUser> newUsers, IEnumerable<string> removeUserExternalIds,
|
||||
bool overwriteExisting);
|
||||
|
@ -11,7 +11,6 @@ using Bit.Core.Enums.Provider;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Tools.Enums;
|
||||
@ -38,7 +37,6 @@ public class OrganizationService : IOrganizationService
|
||||
private readonly IDeviceRepository _deviceRepository;
|
||||
private readonly ILicensingService _licensingService;
|
||||
private readonly IEventService _eventService;
|
||||
private readonly IInstallationRepository _installationRepository;
|
||||
private readonly IApplicationCacheService _applicationCacheService;
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
@ -67,7 +65,6 @@ public class OrganizationService : IOrganizationService
|
||||
IDeviceRepository deviceRepository,
|
||||
ILicensingService licensingService,
|
||||
IEventService eventService,
|
||||
IInstallationRepository installationRepository,
|
||||
IApplicationCacheService applicationCacheService,
|
||||
IPaymentService paymentService,
|
||||
IPolicyRepository policyRepository,
|
||||
@ -95,7 +92,6 @@ public class OrganizationService : IOrganizationService
|
||||
_deviceRepository = deviceRepository;
|
||||
_licensingService = licensingService;
|
||||
_eventService = eventService;
|
||||
_installationRepository = installationRepository;
|
||||
_applicationCacheService = applicationCacheService;
|
||||
_paymentService = paymentService;
|
||||
_policyRepository = policyRepository;
|
||||
@ -1734,54 +1730,6 @@ public class OrganizationService : IOrganizationService
|
||||
EventType.OrganizationUser_UpdatedGroups);
|
||||
}
|
||||
|
||||
public async Task UpdateUserResetPasswordEnrollmentAsync(Guid organizationId, Guid userId, string resetPasswordKey, IUserService userService, Guid? callingUserId)
|
||||
{
|
||||
// Org User must be the same as the calling user and the organization ID associated with the user must match passed org ID
|
||||
var orgUser = await _organizationUserRepository.GetByOrganizationAsync(organizationId, userId);
|
||||
if (!callingUserId.HasValue || orgUser == null || orgUser.UserId != callingUserId.Value ||
|
||||
orgUser.OrganizationId != organizationId)
|
||||
{
|
||||
throw new BadRequestException("User not valid.");
|
||||
}
|
||||
|
||||
// Make sure the organization has the ability to use password reset
|
||||
var org = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
if (org == null || !org.UseResetPassword)
|
||||
{
|
||||
throw new BadRequestException("Organization does not allow password reset enrollment.");
|
||||
}
|
||||
|
||||
// Make sure the organization has the policy enabled
|
||||
var resetPasswordPolicy =
|
||||
await _policyRepository.GetByOrganizationIdTypeAsync(organizationId, PolicyType.ResetPassword);
|
||||
if (resetPasswordPolicy == null || !resetPasswordPolicy.Enabled)
|
||||
{
|
||||
throw new BadRequestException("Organization does not have the password reset policy enabled.");
|
||||
}
|
||||
|
||||
// Block the user from withdrawal if auto enrollment is enabled
|
||||
if (resetPasswordKey == null && resetPasswordPolicy.Data != null)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<ResetPasswordDataModel>(resetPasswordPolicy.Data, JsonHelpers.IgnoreCase);
|
||||
|
||||
if (data?.AutoEnrollEnabled ?? false)
|
||||
{
|
||||
throw new BadRequestException("Due to an Enterprise Policy, you are not allowed to withdraw from Password Reset.");
|
||||
}
|
||||
}
|
||||
|
||||
orgUser.ResetPasswordKey = resetPasswordKey;
|
||||
await _organizationUserRepository.ReplaceAsync(orgUser);
|
||||
await _eventService.LogOrganizationUserEventAsync(orgUser, resetPasswordKey != null ?
|
||||
EventType.OrganizationUser_ResetPassword_Enroll : EventType.OrganizationUser_ResetPassword_Withdraw);
|
||||
|
||||
if (orgUser.Status == OrganizationUserStatusType.Invited)
|
||||
{
|
||||
var user = await _userRepository.GetByIdAsync(userId);
|
||||
await AcceptUserAsync(orgUser, user, userService);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid? invitingUserId, string email,
|
||||
OrganizationUserType type, bool accessAll, string externalId, IEnumerable<CollectionAccessSelection> collections,
|
||||
IEnumerable<Guid> groups)
|
||||
|
Loading…
Reference in New Issue
Block a user