1
0
mirror of https://github.com/bitwarden/server synced 2025-12-16 16:23:31 +00:00

Add disable send policy (#1130)

* Add Disable Send policy

* Test DisableSend policy

* PR Review

* Update tests for using CurrentContext

This required making an interface for CurrentContext and mocking out
the members used. The interface can be expanded as needed for tests.

I moved CurrentContext to a folder, which changes the namespace
and causes a lot of file touches, but most are just adding a reference

* Fix failing test

* Update exemption to include all exempt users

* Move all CurrentContext usages to ICurrentContext

* PR review. Match messaging with Web
This commit is contained in:
Matt Gibson
2021-02-04 12:54:21 -06:00
committed by GitHub
parent 19e7ce8519
commit edd4bc2623
60 changed files with 437 additions and 99 deletions

View File

@@ -1,6 +1,9 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Data;
using Bit.Core.Models.Table;
@@ -14,12 +17,14 @@ namespace Bit.Core.Services
{
private readonly ISendRepository _sendRepository;
private readonly IUserRepository _userRepository;
private readonly IPolicyRepository _policyRepository;
private readonly IUserService _userService;
private readonly IOrganizationRepository _organizationRepository;
private readonly ISendFileStorageService _sendFileStorageService;
private readonly IPasswordHasher<User> _passwordHasher;
private readonly IPushNotificationService _pushService;
private readonly GlobalSettings _globalSettings;
private readonly ICurrentContext _currentContext;
public SendService(
ISendRepository sendRepository,
@@ -29,20 +34,27 @@ namespace Bit.Core.Services
ISendFileStorageService sendFileStorageService,
IPasswordHasher<User> passwordHasher,
IPushNotificationService pushService,
GlobalSettings globalSettings)
GlobalSettings globalSettings,
IPolicyRepository policyRepository,
ICurrentContext currentContext)
{
_sendRepository = sendRepository;
_userRepository = userRepository;
_userService = userService;
_policyRepository = policyRepository;
_organizationRepository = organizationRepository;
_sendFileStorageService = sendFileStorageService;
_passwordHasher = passwordHasher;
_pushService = pushService;
_globalSettings = globalSettings;
_currentContext = currentContext;
}
public async Task SaveSendAsync(Send send)
{
// Make sure user can save Sends
await ValidateUserCanSaveAsync(send.UserId);
if (send.Id == default(Guid))
{
await _sendRepository.CreateAsync(send);
@@ -58,7 +70,7 @@ namespace Bit.Core.Services
public async Task CreateSendAsync(Send send, SendFileData data, Stream stream, long requestLength)
{
if (send.Type != Enums.SendType.File)
if (send.Type != SendType.File)
{
throw new BadRequestException("Send is not of type \"file\".");
}
@@ -174,5 +186,28 @@ namespace Bit.Core.Services
{
return _passwordHasher.HashPassword(new User(), password);
}
private async Task ValidateUserCanSaveAsync(Guid? userId)
{
if (!userId.HasValue || (!_currentContext.Organizations?.Any() ?? true))
{
return;
}
var policies = await _policyRepository.GetManyByUserIdAsync(userId.Value);
if (policies == null)
{
return;
}
foreach (var policy in policies.Where(p => p.Enabled && p.Type == PolicyType.DisableSend))
{
if (!_currentContext.ManagePolicies(policy.OrganizationId))
{
throw new BadRequestException("Due to an Enterprise Policy, you are only able to delete an existing Send.");
}
}
}
}
}