mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 15:42:48 -05: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:
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
@ -181,7 +182,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
||||
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
||||
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||
return currentContext?.DeviceIdentifier;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ using Bit.Core.Models.Data;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Context;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -14,14 +15,14 @@ namespace Bit.Core.Services
|
||||
private readonly IEventWriteService _eventWriteService;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IApplicationCacheService _applicationCacheService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
public EventService(
|
||||
IEventWriteService eventWriteService,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IApplicationCacheService applicationCacheService,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_eventWriteService = eventWriteService;
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Table;
|
||||
using Microsoft.Azure.NotificationHubs;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
@ -206,7 +207,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
||||
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
||||
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||
return currentContext?.DeviceIdentifier;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
@ -187,7 +188,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
||||
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
||||
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||
return currentContext?.DeviceIdentifier;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Enums;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@ -198,7 +199,7 @@ namespace Bit.Core.Services
|
||||
private async Task AddCurrentContextAsync(PushSendRequestModel request, bool addIdentifier)
|
||||
{
|
||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
||||
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
||||
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||
if (!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
||||
{
|
||||
var device = await _deviceRepository.GetByIdentifierAsync(currentContext.DeviceIdentifier);
|
||||
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ using Bit.Core.Models.Business;
|
||||
using U2fLib = U2F.Core.Crypto.U2F;
|
||||
using U2F.Core.Models;
|
||||
using U2F.Core.Utils;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.IO;
|
||||
@ -46,7 +47,7 @@ namespace Bit.Core.Services
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly IDataProtector _organizationServiceDataProtector;
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
|
||||
@ -74,7 +75,7 @@ namespace Bit.Core.Services
|
||||
IPaymentService paymentService,
|
||||
IPolicyRepository policyRepository,
|
||||
IReferenceEventService referenceEventService,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings,
|
||||
IOrganizationService organizationService)
|
||||
: base(
|
||||
|
Reference in New Issue
Block a user