mirror of
https://github.com/bitwarden/server.git
synced 2025-02-16 01:51:21 +01: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:
parent
19e7ce8519
commit
edd4bc2623
@ -136,6 +136,7 @@ namespace Bit.Portal.Controllers
|
||||
case PolicyType.PasswordGenerator:
|
||||
case PolicyType.TwoFactorAuthentication:
|
||||
case PolicyType.PersonalOwnership:
|
||||
case PolicyType.DisableSend:
|
||||
break;
|
||||
|
||||
case PolicyType.SingleOrg:
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
@ -86,6 +86,7 @@ namespace Bit.Portal.Models
|
||||
case PolicyType.TwoFactorAuthentication:
|
||||
case PolicyType.RequireSso:
|
||||
case PolicyType.PersonalOwnership:
|
||||
case PolicyType.DisableSend:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
@ -47,6 +47,11 @@ namespace Bit.Portal.Models
|
||||
DescriptionKey = "PersonalOwnershipDescription";
|
||||
break;
|
||||
|
||||
case PolicyType.DisableSend:
|
||||
NameKey = "DisableSend";
|
||||
DescriptionKey = "DisableSendDescription";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Portal.Utilities;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
@ -40,7 +41,7 @@ namespace Bit.Portal
|
||||
|
||||
// Context
|
||||
services.AddScoped<EnterprisePortalCurrentContext>();
|
||||
services.AddScoped<CurrentContext>((serviceProvider) =>
|
||||
services.AddScoped<ICurrentContext, CurrentContext>((serviceProvider) =>
|
||||
serviceProvider.GetService<EnterprisePortalCurrentContext>());
|
||||
|
||||
// Identity
|
||||
|
@ -61,6 +61,17 @@
|
||||
@i18nService.T("PersonalOwnershipExemption")
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.DisableSend)
|
||||
{
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("DisableSendExemption")
|
||||
</div>
|
||||
}
|
||||
|
||||
<div asp-validation-summary="ModelOnly" class="alert alert-danger"></div>
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Sso.Utilities;
|
||||
using IdentityServer4.Extensions;
|
||||
@ -39,7 +40,7 @@ namespace Bit.Sso
|
||||
services.AddSqlServerRepositories(globalSettings);
|
||||
|
||||
// Context
|
||||
services.AddScoped<CurrentContext>();
|
||||
services.AddScoped<ICurrentContext, CurrentContext>();
|
||||
|
||||
// Mvc
|
||||
services.AddControllersWithViews();
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Jobs;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Identity;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
@ -45,7 +46,7 @@ namespace Bit.Admin
|
||||
services.AddSqlServerRepositories(globalSettings);
|
||||
|
||||
// Context
|
||||
services.AddScoped<CurrentContext>();
|
||||
services.AddScoped<ICurrentContext, CurrentContext>();
|
||||
|
||||
// Identity
|
||||
services.AddPasswordlessIdentityServices<ReadOnlyEnvIdentityUserStore>(globalSettings);
|
||||
|
@ -8,6 +8,7 @@ using Bit.Core.Models.Api;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Api.Utilities;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
@ -23,7 +24,7 @@ namespace Bit.Api.Controllers
|
||||
private readonly ICollectionCipherRepository _collectionCipherRepository;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
public CiphersController(
|
||||
@ -31,7 +32,7 @@ namespace Bit.Api.Controllers
|
||||
ICollectionCipherRepository collectionCipherRepository,
|
||||
ICipherService cipherService,
|
||||
IUserService userService,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_cipherRepository = cipherRepository;
|
||||
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Table;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -20,13 +20,13 @@ namespace Bit.Api.Controllers
|
||||
private readonly ICollectionRepository _collectionRepository;
|
||||
private readonly ICollectionService _collectionService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public CollectionsController(
|
||||
ICollectionRepository collectionRepository,
|
||||
ICollectionService collectionService,
|
||||
IUserService userService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_collectionRepository = collectionRepository;
|
||||
_collectionService = collectionService;
|
||||
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Api.Controllers
|
||||
@ -20,14 +20,14 @@ namespace Bit.Api.Controllers
|
||||
private readonly ICipherRepository _cipherRepository;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IEventRepository _eventRepository;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public EventsController(
|
||||
IUserService userService,
|
||||
ICipherRepository cipherRepository,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IEventRepository eventRepository,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_userService = userService;
|
||||
_cipherRepository = cipherRepository;
|
||||
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Api.Controllers
|
||||
@ -18,12 +18,12 @@ namespace Bit.Api.Controllers
|
||||
{
|
||||
private readonly IGroupRepository _groupRepository;
|
||||
private readonly IGroupService _groupService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public GroupsController(
|
||||
IGroupRepository groupRepository,
|
||||
IGroupService groupService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_groupRepository = groupRepository;
|
||||
_groupService = groupService;
|
||||
|
@ -6,6 +6,7 @@ using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using System.Net;
|
||||
using Bit.Core.Exceptions;
|
||||
using System.Linq;
|
||||
@ -22,7 +23,7 @@ namespace Bit.Api.Controllers
|
||||
private static HttpClient _httpClient;
|
||||
|
||||
private readonly IUserService _userService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly string _userAgent;
|
||||
|
||||
@ -33,7 +34,7 @@ namespace Bit.Api.Controllers
|
||||
|
||||
public HibpController(
|
||||
IUserService userService,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_userService = userService;
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Exceptions;
|
||||
@ -21,7 +21,7 @@ namespace Bit.Api.Controllers
|
||||
private readonly IUserService _userService;
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public LicensesController(
|
||||
ILicensingService licensingService,
|
||||
@ -29,7 +29,7 @@ namespace Bit.Api.Controllers
|
||||
IUserService userService,
|
||||
IOrganizationRepository organizationRepository,
|
||||
IOrganizationService organizationService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_licensingService = licensingService;
|
||||
_userRepository = userRepository;
|
||||
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Models.Business;
|
||||
|
||||
@ -23,7 +23,7 @@ namespace Bit.Api.Controllers
|
||||
private readonly ICollectionRepository _collectionRepository;
|
||||
private readonly IGroupRepository _groupRepository;
|
||||
private readonly IUserService _userService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public OrganizationUsersController(
|
||||
IOrganizationRepository organizationRepository,
|
||||
@ -32,7 +32,7 @@ namespace Bit.Api.Controllers
|
||||
ICollectionRepository collectionRepository,
|
||||
IGroupRepository groupRepository,
|
||||
IUserService userService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
|
@ -9,6 +9,7 @@ using Bit.Core.Models.Api;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Api.Utilities;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Utilities;
|
||||
@ -24,7 +25,7 @@ namespace Bit.Api.Controllers
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
|
||||
@ -34,7 +35,7 @@ namespace Bit.Api.Controllers
|
||||
IOrganizationService organizationService,
|
||||
IUserService userService,
|
||||
IPaymentService paymentService,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings,
|
||||
IPolicyRepository policyRepository)
|
||||
{
|
||||
|
@ -8,6 +8,7 @@ using Bit.Core.Models.Api;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
@ -23,7 +24,7 @@ namespace Bit.Api.Controllers
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IUserService _userService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IDataProtector _organizationServiceDataProtector;
|
||||
|
||||
@ -33,7 +34,7 @@ namespace Bit.Api.Controllers
|
||||
IOrganizationService organizationService,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IUserService userService,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings,
|
||||
IDataProtectionProvider dataProtectionProvider)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Api;
|
||||
using System.Threading.Tasks;
|
||||
@ -21,14 +22,14 @@ namespace Bit.Api.Controllers
|
||||
private readonly IPushRegistrationService _pushRegistrationService;
|
||||
private readonly IPushNotificationService _pushNotificationService;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
public PushController(
|
||||
IPushRegistrationService pushRegistrationService,
|
||||
IPushNotificationService pushNotificationService,
|
||||
IWebHostEnvironment environment,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_currentContext = currentContext;
|
||||
|
@ -10,6 +10,7 @@ using Bit.Core.Models.Table;
|
||||
using Bit.Core.Enums;
|
||||
using System.Linq;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Utilities.Duo;
|
||||
@ -25,7 +26,7 @@ namespace Bit.Api.Controllers
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly UserManager<User> _userManager;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public TwoFactorController(
|
||||
IUserService userService,
|
||||
@ -33,7 +34,7 @@ namespace Bit.Api.Controllers
|
||||
IOrganizationService organizationService,
|
||||
GlobalSettings globalSettings,
|
||||
UserManager<User> userManager,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_userService = userService;
|
||||
_organizationRepository = organizationRepository;
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Api.Public;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
@ -17,12 +17,12 @@ namespace Bit.Api.Public.Controllers
|
||||
{
|
||||
private readonly ICollectionRepository _collectionRepository;
|
||||
private readonly ICollectionService _collectionService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public CollectionsController(
|
||||
ICollectionRepository collectionRepository,
|
||||
ICollectionService collectionService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_collectionRepository = collectionRepository;
|
||||
_collectionService = collectionService;
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Api.Public;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
@ -17,12 +17,12 @@ namespace Bit.Api.Public.Controllers
|
||||
{
|
||||
private readonly IEventRepository _eventRepository;
|
||||
private readonly ICipherRepository _cipherRepository;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public EventsController(
|
||||
IEventRepository eventRepository,
|
||||
ICipherRepository cipherRepository,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_eventRepository = eventRepository;
|
||||
_cipherRepository = cipherRepository;
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Api.Public;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
@ -18,12 +18,12 @@ namespace Bit.Api.Public.Controllers
|
||||
{
|
||||
private readonly IGroupRepository _groupRepository;
|
||||
private readonly IGroupService _groupService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public GroupsController(
|
||||
IGroupRepository groupRepository,
|
||||
IGroupService groupService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_groupRepository = groupRepository;
|
||||
_groupService = groupService;
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Api.Public;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Repositories;
|
||||
@ -21,14 +21,14 @@ namespace Bit.Api.Public.Controllers
|
||||
private readonly IGroupRepository _groupRepository;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public MembersController(
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IGroupRepository groupRepository,
|
||||
IOrganizationService organizationService,
|
||||
IUserService userService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
_groupRepository = groupRepository;
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Api.Public;
|
||||
using Bit.Core.Services;
|
||||
@ -15,12 +16,12 @@ namespace Bit.Api.Public.Controllers
|
||||
public class OrganizationController : Controller
|
||||
{
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
public OrganizationController(
|
||||
IOrganizationService organizationService,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_organizationService = organizationService;
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api.Public;
|
||||
using Bit.Core.Repositories;
|
||||
@ -20,14 +20,14 @@ namespace Bit.Api.Public.Controllers
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public PoliciesController(
|
||||
IPolicyRepository policyRepository,
|
||||
IPolicyService policyService,
|
||||
IUserService userService,
|
||||
IOrganizationService organizationService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_policyRepository = policyRepository;
|
||||
_policyService = policyService;
|
||||
|
@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Bit.Api.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Identity;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using AspNetCoreRateLimit;
|
||||
@ -54,7 +55,7 @@ namespace Bit.Api
|
||||
services.AddSqlServerRepositories(globalSettings);
|
||||
|
||||
// Context
|
||||
services.AddScoped<CurrentContext>();
|
||||
services.AddScoped<ICurrentContext, CurrentContext>();
|
||||
|
||||
// Caching
|
||||
services.AddMemoryCache();
|
||||
|
@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Stripe;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@ -46,7 +47,7 @@ namespace Bit.Billing
|
||||
services.AddSingleton<BitPayClient>();
|
||||
|
||||
// Context
|
||||
services.AddScoped<CurrentContext>();
|
||||
services.AddScoped<ICurrentContext, CurrentContext>();
|
||||
|
||||
// Identity
|
||||
services.AddCustomIdentityServices(globalSettings);
|
||||
|
24
src/Core/Context/CurrentContentOrganization.cs
Normal file
24
src/Core/Context/CurrentContentOrganization.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Context
|
||||
{
|
||||
public class CurrentContentOrganization
|
||||
{
|
||||
public CurrentContentOrganization() { }
|
||||
|
||||
public CurrentContentOrganization(OrganizationUser orgUser)
|
||||
{
|
||||
Id = orgUser.OrganizationId;
|
||||
Type = orgUser.Type;
|
||||
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(orgUser.Permissions);
|
||||
}
|
||||
|
||||
public Guid Id { get; set; }
|
||||
public OrganizationUserType Type { get; set; }
|
||||
public Permissions Permissions { get; set; }
|
||||
}
|
||||
}
|
@ -10,9 +10,9 @@ using System.Security.Claims;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Core
|
||||
namespace Bit.Core.Context
|
||||
{
|
||||
public class CurrentContext
|
||||
public class CurrentContext : ICurrentContext
|
||||
{
|
||||
private bool _builtHttpContext;
|
||||
private bool _builtClaimsPrincipal;
|
||||
@ -296,21 +296,5 @@ namespace Bit.Core
|
||||
ManageUsers = hasClaim("manageusers")
|
||||
};
|
||||
}
|
||||
|
||||
public class CurrentContentOrganization
|
||||
{
|
||||
public CurrentContentOrganization() { }
|
||||
|
||||
public CurrentContentOrganization(OrganizationUser orgUser)
|
||||
{
|
||||
Id = orgUser.OrganizationId;
|
||||
Type = orgUser.Type;
|
||||
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(orgUser.Permissions);
|
||||
}
|
||||
|
||||
public Guid Id { get; set; }
|
||||
public OrganizationUserType Type { get; set; }
|
||||
public Permissions Permissions { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
49
src/Core/Context/ICurrentContext.cs
Normal file
49
src/Core/Context/ICurrentContext.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Repositories;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Bit.Core.Context
|
||||
{
|
||||
public interface ICurrentContext
|
||||
{
|
||||
HttpContext HttpContext { get; set; }
|
||||
Guid? UserId { get; set; }
|
||||
User User { get; set; }
|
||||
string DeviceIdentifier { get; set; }
|
||||
DeviceType? DeviceType { get; set; }
|
||||
string IpAddress { get; set; }
|
||||
List<CurrentContentOrganization> Organizations { get; set; }
|
||||
Guid? InstallationId { get; set; }
|
||||
Guid? OrganizationId { get; set; }
|
||||
|
||||
Task BuildAsync(HttpContext httpContext, GlobalSettings globalSettings);
|
||||
Task BuildAsync(ClaimsPrincipal user, GlobalSettings globalSettings);
|
||||
|
||||
Task SetContextAsync(ClaimsPrincipal user);
|
||||
|
||||
|
||||
bool OrganizationUser(Guid orgId);
|
||||
bool OrganizationManager(Guid orgId);
|
||||
bool OrganizationAdmin(Guid orgId);
|
||||
bool OrganizationOwner(Guid orgId);
|
||||
bool OrganizationCustom(Guid orgId);
|
||||
bool AccessBusinessPortal(Guid orgId);
|
||||
bool AccessEventLogs(Guid orgId);
|
||||
bool AccessImportExport(Guid orgId);
|
||||
bool AccessReports(Guid orgId);
|
||||
bool ManageAllCollections(Guid orgId);
|
||||
bool ManageAssignedCollections(Guid orgId);
|
||||
bool ManageGroups(Guid orgId);
|
||||
bool ManagePolicies(Guid orgId);
|
||||
bool ManageSso(Guid orgId);
|
||||
bool ManageUsers(Guid orgId);
|
||||
|
||||
Task<ICollection<CurrentContentOrganization>> OrganizationMembershipAsync(
|
||||
IOrganizationUserRepository organizationUserRepository, Guid userId);
|
||||
}
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
SingleOrg = 3,
|
||||
RequireSso = 4,
|
||||
PersonalOwnership = 5,
|
||||
DisableSend = 6,
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Identity;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Context;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Bit.Core.Identity
|
||||
@ -18,12 +19,12 @@ namespace Bit.Core.Identity
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public UserStore(
|
||||
IServiceProvider serviceProvider,
|
||||
IUserRepository userRepository,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_userRepository = userRepository;
|
||||
|
@ -17,6 +17,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Context;
|
||||
|
||||
namespace Bit.Core.IdentityServer
|
||||
{
|
||||
@ -33,7 +34,7 @@ namespace Bit.Core.IdentityServer
|
||||
private readonly IApplicationCacheService _applicationCacheService;
|
||||
private readonly IMailService _mailService;
|
||||
private readonly ILogger<ResourceOwnerPasswordValidator> _logger;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
|
||||
@ -49,7 +50,7 @@ namespace Bit.Core.IdentityServer
|
||||
IApplicationCacheService applicationCacheService,
|
||||
IMailService mailService,
|
||||
ILogger<ResourceOwnerPasswordValidator> logger,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings,
|
||||
IPolicyRepository policyRepository)
|
||||
{
|
||||
|
@ -9,6 +9,7 @@ using IdentityModel;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Security.Claims;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Context;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Bit.Core.IdentityServer
|
||||
@ -21,7 +22,7 @@ namespace Bit.Core.IdentityServer
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly StaticClientStore _staticClientStore;
|
||||
private readonly ILicensingService _licensingService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
|
||||
public ClientStore(
|
||||
@ -31,7 +32,7 @@ namespace Bit.Core.IdentityServer
|
||||
GlobalSettings globalSettings,
|
||||
StaticClientStore staticClientStore,
|
||||
ILicensingService licensingService,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
IOrganizationUserRepository organizationUserRepository)
|
||||
{
|
||||
_installationRepository = installationRepository;
|
||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Context;
|
||||
using System.Linq;
|
||||
using Bit.Core.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@ -31,7 +32,7 @@ namespace Bit.Core.IdentityServer
|
||||
IApplicationCacheService applicationCacheService,
|
||||
IMailService mailService,
|
||||
ILogger<ResourceOwnerPasswordValidator> logger,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings,
|
||||
IPolicyRepository policyRepository)
|
||||
: base(userManager, deviceRepository, deviceService, userService, eventService,
|
||||
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||
using System;
|
||||
using IdentityModel;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Context;
|
||||
|
||||
namespace Bit.Core.IdentityServer
|
||||
{
|
||||
@ -17,13 +18,13 @@ namespace Bit.Core.IdentityServer
|
||||
private readonly IUserService _userService;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly ILicensingService _licensingService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
|
||||
public ProfileService(
|
||||
IUserService userService,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
ILicensingService licensingService,
|
||||
CurrentContext currentContext)
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
_userService = userService;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
|
@ -8,6 +8,7 @@ using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Identity;
|
||||
using Bit.Core.Context;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Bit.Core.IdentityServer
|
||||
@ -30,7 +31,7 @@ namespace Bit.Core.IdentityServer
|
||||
IApplicationCacheService applicationCacheService,
|
||||
IMailService mailService,
|
||||
ILogger<ResourceOwnerPasswordValidator> logger,
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings,
|
||||
IPolicyRepository policyRepository)
|
||||
: base(userManager, deviceRepository, deviceService, userService, eventService,
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Context;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
@ -7,7 +8,7 @@ namespace Bit.Core.Models.Data
|
||||
{
|
||||
public EventMessage() { }
|
||||
|
||||
public EventMessage(CurrentContext currentContext)
|
||||
public EventMessage(ICurrentContext currentContext)
|
||||
: base()
|
||||
{
|
||||
IpAddress = currentContext.IpAddress;
|
||||
|
@ -585,6 +585,17 @@
|
||||
<value>Require users to save vault items to an organization by removing the personal ownership option.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipExemption" xml:space="preserve">
|
||||
<value>Organization users that can manage the organization's policies are exempt from this policy's enforcement.</value>
|
||||
</data>
|
||||
<data name="DisableSend" xml:space="preserve">
|
||||
<value>Disable Send</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="DisableSendDescription" xml:space="preserve">
|
||||
<value>Do not allow users to create or edit a Bitwarden Send. Deleting an existing Send is still allowed.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="DisableSendExemption" xml:space="preserve">
|
||||
<value>Organization Owners and Administrators are exempt from this policy's enforcement.</value>
|
||||
</data>
|
||||
<data name="DisableRequireSsoError" xml:space="preserve">
|
||||
|
@ -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(
|
||||
|
@ -15,6 +15,7 @@ using System.Globalization;
|
||||
using System.Web;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Context;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Storage;
|
||||
using Microsoft.Azure.Storage.Blob;
|
||||
@ -685,7 +686,7 @@ namespace Bit.Core.Utilities
|
||||
return configDict;
|
||||
}
|
||||
|
||||
public static List<KeyValuePair<string, string>> BuildIdentityClaims(User user, ICollection<CurrentContext.CurrentContentOrganization> orgs, bool isPremium)
|
||||
public static List<KeyValuePair<string, string>> BuildIdentityClaims(User user, ICollection<CurrentContentOrganization> orgs, bool isPremium)
|
||||
{
|
||||
var claims = new List<KeyValuePair<string, string>>()
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
@ -12,7 +13,7 @@ namespace Bit.Core.Utilities
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext httpContext, CurrentContext currentContext, GlobalSettings globalSettings)
|
||||
public async Task Invoke(HttpContext httpContext, ICurrentContext currentContext, GlobalSettings globalSettings)
|
||||
{
|
||||
await currentContext.BuildAsync(httpContext, globalSettings);
|
||||
await _next.Invoke(httpContext);
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Repositories;
|
||||
@ -18,12 +18,12 @@ namespace Bit.Events.Controllers
|
||||
[Authorize("Application")]
|
||||
public class CollectController : Controller
|
||||
{
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly IEventService _eventService;
|
||||
private readonly ICipherRepository _cipherRepository;
|
||||
|
||||
public CollectController(
|
||||
CurrentContext currentContext,
|
||||
ICurrentContext currentContext,
|
||||
IEventService eventService,
|
||||
ICipherRepository cipherRepository)
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Globalization;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using IdentityModel;
|
||||
@ -35,7 +36,7 @@ namespace Bit.Events
|
||||
services.AddSqlServerRepositories(globalSettings);
|
||||
|
||||
// Context
|
||||
services.AddScoped<CurrentContext>();
|
||||
services.AddScoped<ICurrentContext, CurrentContext>();
|
||||
|
||||
// Identity
|
||||
services.AddIdentityAuthenticationServices(globalSettings, Environment, config =>
|
||||
|
@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Utilities;
|
||||
using AspNetCoreRateLimit;
|
||||
using System.Globalization;
|
||||
@ -49,7 +50,7 @@ namespace Bit.Identity
|
||||
services.AddSqlServerRepositories(globalSettings);
|
||||
|
||||
// Context
|
||||
services.AddScoped<CurrentContext>();
|
||||
services.AddScoped<ICurrentContext, CurrentContext>();
|
||||
|
||||
// Caching
|
||||
services.AddMemoryCache();
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace Bit.Notifications
|
||||
|
39
test/Core.Test/AutoFixture/CurrentContextFixtures.cs
Normal file
39
test/Core.Test/AutoFixture/CurrentContextFixtures.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AutoFixture;
|
||||
using AutoFixture.Kernel;
|
||||
using Bit.Core.Context;
|
||||
|
||||
namespace Bit.Core.Test.AutoFixture.CurrentContextFixtures
|
||||
{
|
||||
internal class CurrentContext : ICustomization
|
||||
{
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
fixture.Customizations.Add(new CurrentContextBuilder());
|
||||
}
|
||||
}
|
||||
|
||||
internal class CurrentContextBuilder : ISpecimenBuilder
|
||||
{
|
||||
public object Create(object request, ISpecimenContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
if (!(request is Type typeRequest))
|
||||
{
|
||||
return new NoSpecimen();
|
||||
}
|
||||
if (typeof(ICurrentContext) != typeRequest)
|
||||
{
|
||||
return new NoSpecimen();
|
||||
}
|
||||
|
||||
var obj = new Fixture().WithAutoNSubstitutions().Create<ICurrentContext>();
|
||||
obj.Organizations = context.Create<List<CurrentContentOrganization>>();
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
65
test/Core.Test/AutoFixture/SendFixtures.cs
Normal file
65
test/Core.Test/AutoFixture/SendFixtures.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using AutoFixture;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Test.AutoFixture.Attributes;
|
||||
|
||||
namespace Bit.Core.Test.AutoFixture.SendFixtures
|
||||
{
|
||||
internal class OrganizationSend : ICustomization
|
||||
{
|
||||
public Guid? OrganizationId { get; set; }
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
fixture.Customize<Send>(composer => composer
|
||||
.With(s => s.OrganizationId, OrganizationId ?? Guid.NewGuid())
|
||||
.Without(s => s.UserId));
|
||||
}
|
||||
}
|
||||
|
||||
internal class UserSend : ICustomization
|
||||
{
|
||||
public Guid? UserId { get; set; }
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
fixture.Customize<Send>(composer => composer
|
||||
.With(s => s.UserId, UserId ?? Guid.NewGuid())
|
||||
.Without(s => s.OrganizationId));
|
||||
}
|
||||
}
|
||||
|
||||
internal class UserSendAutoDataAttribute : CustomAutoDataAttribute
|
||||
{
|
||||
public UserSendAutoDataAttribute(string userId = null) : base(new SutProviderCustomization(),
|
||||
new UserSend { UserId = userId == null ? (Guid?)null : new Guid(userId) })
|
||||
{ }
|
||||
}
|
||||
internal class InlineUserSendAutoDataAttribute : InlineCustomAutoDataAttribute
|
||||
{
|
||||
public InlineUserSendAutoDataAttribute(params object[] values) : base(new[] { typeof(CurrentContextFixtures.CurrentContext),
|
||||
typeof(SutProviderCustomization), typeof(UserSend) }, values)
|
||||
{ }
|
||||
}
|
||||
|
||||
internal class InlineKnownUserSendAutoDataAttribute : InlineCustomAutoDataAttribute
|
||||
{
|
||||
public InlineKnownUserSendAutoDataAttribute(string userId, params object[] values) : base(new ICustomization[]
|
||||
{ new CurrentContextFixtures.CurrentContext(), new SutProviderCustomization(),
|
||||
new UserSend { UserId = new Guid(userId) } }, values)
|
||||
{ }
|
||||
}
|
||||
|
||||
internal class OrganizationSendAutoDataAttribute : CustomAutoDataAttribute
|
||||
{
|
||||
public OrganizationSendAutoDataAttribute(string organizationId = null) : base(new CurrentContextFixtures.CurrentContext(),
|
||||
new SutProviderCustomization(),
|
||||
new OrganizationSend { OrganizationId = organizationId == null ? (Guid?)null : new Guid(organizationId) })
|
||||
{ }
|
||||
}
|
||||
|
||||
internal class InlineOrganizationSendAutoDataAttribute : InlineCustomAutoDataAttribute
|
||||
{
|
||||
public InlineOrganizationSendAutoDataAttribute(params object[] values) : base(new[] { typeof(CurrentContextFixtures.CurrentContext),
|
||||
typeof(SutProviderCustomization), typeof(OrganizationSend) }, values)
|
||||
{ }
|
||||
}
|
||||
}
|
@ -16,10 +16,12 @@ namespace Bit.Core.Test.AutoFixture
|
||||
public TSut Sut { get; private set; }
|
||||
public Type SutType => typeof(TSut);
|
||||
|
||||
public SutProvider()
|
||||
public SutProvider() : this(new Fixture()) { }
|
||||
|
||||
public SutProvider(IFixture fixture)
|
||||
{
|
||||
_dependencies = new Dictionary<Type, Dictionary<string, object>>();
|
||||
_fixture = new Fixture().WithAutoNSubstitutions();
|
||||
_fixture = (fixture ?? new Fixture()).WithAutoNSubstitutions();
|
||||
_constructorParameterRelay = new ConstructorParameterRelay<TSut>(this, _fixture);
|
||||
_fixture.Customizations.Add(_constructorParameterRelay);
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ namespace Bit.Core.Test.AutoFixture
|
||||
{
|
||||
public class SutProviderCustomization : ICustomization, ISpecimenBuilder
|
||||
{
|
||||
private IFixture _fixture = null;
|
||||
|
||||
public object Create(object request, ISpecimenContext context)
|
||||
{
|
||||
if (context == null)
|
||||
@ -21,11 +23,12 @@ namespace Bit.Core.Test.AutoFixture
|
||||
return new NoSpecimen();
|
||||
}
|
||||
|
||||
return ((ISutProvider)Activator.CreateInstance(typeRequest)).Create();
|
||||
return ((ISutProvider)Activator.CreateInstance(typeRequest, _fixture)).Create();
|
||||
}
|
||||
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
fixture.Customizations.Add(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using NSubstitute;
|
||||
|
74
test/Core.Test/Services/SendServiceTests.cs
Normal file
74
test/Core.Test/Services/SendServiceTests.cs
Normal file
@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.AutoFixture;
|
||||
using Bit.Core.Test.AutoFixture.SendFixtures;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Services
|
||||
{
|
||||
public class SendServiceTests
|
||||
{
|
||||
private void SaveSendAsync_Setup(SendType sendType, bool canManagePolicies,
|
||||
SutProvider<SendService> sutProvider, Send send, List<Policy> policies)
|
||||
{
|
||||
send.Id = default;
|
||||
send.Type = sendType;
|
||||
|
||||
policies.First().Type = PolicyType.DisableSend;
|
||||
policies.First().Enabled = true;
|
||||
|
||||
sutProvider.GetDependency<IPolicyRepository>().GetManyByUserIdAsync(send.UserId.Value).Returns(policies);
|
||||
sutProvider.GetDependency<ICurrentContext>().ManagePolicies(Arg.Any<Guid>()).Returns(canManagePolicies);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineUserSendAutoData(SendType.File)]
|
||||
[InlineUserSendAutoData(SendType.Text)]
|
||||
public async void SaveSendAsync_DisableSend_CantManagePolicies_throws(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send, List<Policy> policies)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, canManagePolicies: false, sutProvider, send, policies);
|
||||
|
||||
await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.SaveSendAsync(send));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineUserSendAutoData(SendType.File)]
|
||||
[InlineUserSendAutoData(SendType.Text)]
|
||||
public async void SaveSendAsync_DisableSend_DisabledPolicy_CantManagePolicies_success(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send, List<Policy> policies)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, canManagePolicies: false, sutProvider, send, policies);
|
||||
foreach (var policy in policies.Where(p => p.Type == PolicyType.DisableSend))
|
||||
{
|
||||
policy.Enabled = false;
|
||||
}
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineUserSendAutoData(SendType.File)]
|
||||
[InlineUserSendAutoData(SendType.Text)]
|
||||
public async void SaveSendAsync_DisableSend_CanManagePolicies_success(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send, List<Policy> policies)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, canManagePolicies: true, sutProvider, send, policies);
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
using Bit.Core.Context;
|
||||
|
||||
namespace Bit.Core.Test.Services
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user