mirror of
https://github.com/bitwarden/server.git
synced 2025-01-30 23:11:22 +01:00
Merge branch 'main' into ac/ac-1682/ef-migrations
This commit is contained in:
commit
0f3aa5d1ae
@ -7,7 +7,7 @@
|
||||
"commands": ["swagger"]
|
||||
},
|
||||
"dotnet-ef": {
|
||||
"version": "8.0.1",
|
||||
"version": "8.0.2",
|
||||
"commands": ["dotnet-ef"]
|
||||
}
|
||||
}
|
||||
|
1
.github/codecov.yml
vendored
1
.github/codecov.yml
vendored
@ -1,2 +1,3 @@
|
||||
ignore:
|
||||
- "test" # Tests
|
||||
- "util" # Utils (migrators)
|
||||
|
40
.github/workflows/build.yml
vendored
40
.github/workflows/build.yml
vendored
@ -119,6 +119,8 @@ jobs:
|
||||
build-docker:
|
||||
name: Build Docker images
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
security-events: write
|
||||
needs: build-artifacts
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@ -173,7 +175,7 @@ jobs:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
|
||||
|
||||
- name: Check Branch to Publish
|
||||
- name: Check branch to publish
|
||||
env:
|
||||
PUBLISH_BRANCHES: "main,rc,hotfix-rc"
|
||||
id: publish-branch-check
|
||||
@ -192,7 +194,7 @@ jobs:
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
|
||||
- name: Login to PROD ACR
|
||||
- name: Log in to ACR - production subscription
|
||||
run: az acr login -n bitwardenprod
|
||||
|
||||
- name: Log in to Azure - CI subscription
|
||||
@ -200,7 +202,7 @@ jobs:
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve github PAT secrets
|
||||
- name: Retrieve GitHub PAT secrets
|
||||
id: retrieve-secret-pat
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
@ -232,19 +234,20 @@ jobs:
|
||||
echo "PROJECT_NAME: $PROJECT_NAME"
|
||||
echo "project_name=$PROJECT_NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate image name(s)
|
||||
id: image-names
|
||||
- name: Generate image tags(s)
|
||||
id: image-tags
|
||||
env:
|
||||
IMAGE_TAG: ${{ steps.tag.outputs.image_tag }}
|
||||
PROJECT_NAME: ${{ steps.setup.outputs.project_name }}
|
||||
SHA: ${{ github.sha }}
|
||||
run: |
|
||||
NAMES="${_AZ_REGISTRY}/${PROJECT_NAME}:${IMAGE_TAG}"
|
||||
TAGS="${_AZ_REGISTRY}/${PROJECT_NAME}:${IMAGE_TAG}"
|
||||
echo "primary_tag=$TAGS" >> $GITHUB_OUTPUT
|
||||
if [[ "${IMAGE_TAG}" == "dev" ]]; then
|
||||
SHORT_SHA=$(git rev-parse --short ${SHA})
|
||||
NAMES=$NAMES",${_AZ_REGISTRY}/${PROJECT_NAME}:dev-${SHORT_SHA}"
|
||||
TAGS=$TAGS",${_AZ_REGISTRY}/${PROJECT_NAME}:dev-${SHORT_SHA}"
|
||||
fi
|
||||
echo "names=$NAMES" >> $GITHUB_OUTPUT
|
||||
echo "tags=$TAGS" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get build artifact
|
||||
if: ${{ matrix.dotnet }}
|
||||
@ -266,10 +269,23 @@ jobs:
|
||||
file: ${{ matrix.base_path }}/${{ matrix.project_name }}/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ${{ steps.image-names.outputs.names }}
|
||||
tags: ${{ steps.image-tags.outputs.tags }}
|
||||
secrets: |
|
||||
"GH_PAT=${{ steps.retrieve-secret-pat.outputs.github-pat-bitwarden-devops-bot-repo-scope }}"
|
||||
|
||||
- name: Scan Docker image
|
||||
id: container-scan
|
||||
uses: anchore/scan-action@3343887d815d7b07465f6fdcd395bd66508d486a # v3.6.4
|
||||
with:
|
||||
image: ${{ steps.image-tags.outputs.primary_tag }}
|
||||
fail-build: false
|
||||
output-format: sarif
|
||||
|
||||
- name: Upload Grype results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2
|
||||
with:
|
||||
sarif_file: ${{ steps.container-scan.outputs.sarif }}
|
||||
|
||||
upload:
|
||||
name: Upload
|
||||
runs-on: ubuntu-22.04
|
||||
@ -286,7 +302,7 @@ jobs:
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
|
||||
- name: Login to PROD ACR
|
||||
- name: Log in to ACR - production subscription
|
||||
run: az acr login -n $_AZ_REGISTRY --only-show-errors
|
||||
|
||||
- name: Make Docker stubs
|
||||
@ -453,7 +469,7 @@ jobs:
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve github PAT secrets
|
||||
- name: Retrieve GitHub PAT secrets
|
||||
id: retrieve-secret-pat
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
@ -486,7 +502,7 @@ jobs:
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve github PAT secrets
|
||||
- name: Retrieve GitHub PAT secrets
|
||||
id: retrieve-secret-pat
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
|
60
.github/workflows/scan.yml
vendored
Normal file
60
.github/workflows/scan.yml
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
name: Scan
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "rc"
|
||||
- "hotfix-rc"
|
||||
pull_request:
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
sast:
|
||||
name: SAST scan
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Scan with Checkmarx
|
||||
uses: checkmarx/ast-github-action@749fec53e0db0f6404a97e2e0807c3e80e3583a7 #2.0.23
|
||||
env:
|
||||
INCREMENTAL: "${{ github.event_name == 'pull_request' && '--sast-incremental' || '' }}"
|
||||
with:
|
||||
project_name: ${{ github.repository }}
|
||||
cx_tenant: ${{ secrets.CHECKMARX_TENANT }}
|
||||
base_uri: https://ast.checkmarx.net/
|
||||
cx_client_id: ${{ secrets.CHECKMARX_CLIENT_ID }}
|
||||
cx_client_secret: ${{ secrets.CHECKMARX_SECRET }}
|
||||
additional_params: --report-format sarif --output-path . ${{ env.INCREMENTAL }}
|
||||
|
||||
- name: Upload Checkmarx results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2
|
||||
with:
|
||||
sarif_file: cx_result.sarif
|
||||
|
||||
quality:
|
||||
name: Quality scan
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Scan with SonarCloud
|
||||
uses: sonarsource/sonarcloud-github-action@49e6cd3b187936a73b8280d59ffd9da69df63ec9 # v2.1.1
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
args: >
|
||||
-Dsonar.organization=${{ github.repository_owner }}
|
||||
-Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }}
|
||||
-Dsonar.test.exclusions=test/**
|
||||
-Dsonar.tests=test/
|
@ -116,6 +116,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqliteMigrations", "util\Sq
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MsSqlMigratorUtility", "util\MsSqlMigratorUtility\MsSqlMigratorUtility.csproj", "{D9A2CCBB-FB0A-4BBA-A9ED-BA9FF277C880}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.Test", "test\Admin.Test\Admin.Test.csproj", "{52D22B52-26D3-463A-8EB5-7FDC849D3761}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Events.Test", "test\Events.Test\Events.Test.csproj", "{916AFD8C-30AF-49B6-A5C9-28CA1B5D9298}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventsProcessor.Test", "test\EventsProcessor.Test\EventsProcessor.Test.csproj", "{81673EFB-7134-4B4B-A32F-1EA05F0EF3CE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notifications.Test", "test\Notifications.Test\Notifications.Test.csproj", "{90D85D8F-5577-4570-A96E-5A2E185F0F6F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -284,6 +292,22 @@ Global
|
||||
{D9A2CCBB-FB0A-4BBA-A9ED-BA9FF277C880}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D9A2CCBB-FB0A-4BBA-A9ED-BA9FF277C880}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D9A2CCBB-FB0A-4BBA-A9ED-BA9FF277C880}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{52D22B52-26D3-463A-8EB5-7FDC849D3761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{52D22B52-26D3-463A-8EB5-7FDC849D3761}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{52D22B52-26D3-463A-8EB5-7FDC849D3761}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{52D22B52-26D3-463A-8EB5-7FDC849D3761}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{916AFD8C-30AF-49B6-A5C9-28CA1B5D9298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{916AFD8C-30AF-49B6-A5C9-28CA1B5D9298}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{916AFD8C-30AF-49B6-A5C9-28CA1B5D9298}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{916AFD8C-30AF-49B6-A5C9-28CA1B5D9298}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{81673EFB-7134-4B4B-A32F-1EA05F0EF3CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{81673EFB-7134-4B4B-A32F-1EA05F0EF3CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{81673EFB-7134-4B4B-A32F-1EA05F0EF3CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{81673EFB-7134-4B4B-A32F-1EA05F0EF3CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{90D85D8F-5577-4570-A96E-5A2E185F0F6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{90D85D8F-5577-4570-A96E-5A2E185F0F6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{90D85D8F-5577-4570-A96E-5A2E185F0F6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{90D85D8F-5577-4570-A96E-5A2E185F0F6F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -329,6 +353,10 @@ Global
|
||||
{7E9A7DD5-EB78-4AC5-BFD5-64573FD2533B} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||
{07143DFA-F242-47A4-A15E-39C9314D4140} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
||||
{D9A2CCBB-FB0A-4BBA-A9ED-BA9FF277C880} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
||||
{52D22B52-26D3-463A-8EB5-7FDC849D3761} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||
{916AFD8C-30AF-49B6-A5C9-28CA1B5D9298} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||
{81673EFB-7134-4B4B-A32F-1EA05F0EF3CE} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||
{90D85D8F-5577-4570-A96E-5A2E185F0F6F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E01CBF68-2E20-425F-9EDB-E0A6510CA92F}
|
||||
|
@ -84,22 +84,29 @@ public class ServiceAccountRepository : Repository<Core.SecretsManager.Entities.
|
||||
|
||||
public async Task DeleteManyByIdAsync(IEnumerable<Guid> ids)
|
||||
{
|
||||
var targetIds = ids.ToList();
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
|
||||
await using var transaction = await dbContext.Database.BeginTransactionAsync();
|
||||
|
||||
// Policies can't have a cascade delete, so we need to delete them manually.
|
||||
var policies = dbContext.AccessPolicies.Where(ap =>
|
||||
((ServiceAccountProjectAccessPolicy)ap).ServiceAccountId.HasValue && ids.Contains(((ServiceAccountProjectAccessPolicy)ap).ServiceAccountId!.Value) ||
|
||||
((GroupServiceAccountAccessPolicy)ap).GrantedServiceAccountId.HasValue && ids.Contains(((GroupServiceAccountAccessPolicy)ap).GrantedServiceAccountId!.Value) ||
|
||||
((UserServiceAccountAccessPolicy)ap).GrantedServiceAccountId.HasValue && ids.Contains(((UserServiceAccountAccessPolicy)ap).GrantedServiceAccountId!.Value));
|
||||
dbContext.RemoveRange(policies);
|
||||
await dbContext.AccessPolicies.Where(ap =>
|
||||
targetIds.Contains(((ServiceAccountProjectAccessPolicy)ap).ServiceAccountId!.Value) ||
|
||||
targetIds.Contains(((ServiceAccountSecretAccessPolicy)ap).ServiceAccountId!.Value) ||
|
||||
targetIds.Contains(((GroupServiceAccountAccessPolicy)ap).GrantedServiceAccountId!.Value) ||
|
||||
targetIds.Contains(((UserServiceAccountAccessPolicy)ap).GrantedServiceAccountId!.Value))
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
var apiKeys = dbContext.ApiKeys.Where(a => a.ServiceAccountId.HasValue && ids.Contains(a.ServiceAccountId!.Value));
|
||||
dbContext.RemoveRange(apiKeys);
|
||||
await dbContext.ApiKeys
|
||||
.Where(a => targetIds.Contains(a.ServiceAccountId!.Value))
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
var serviceAccounts = dbContext.ServiceAccount.Where(c => ids.Contains(c.Id));
|
||||
dbContext.RemoveRange(serviceAccounts);
|
||||
await dbContext.SaveChangesAsync();
|
||||
await dbContext.ServiceAccount
|
||||
.Where(c => targetIds.Contains(c.Id))
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
|
||||
public async Task<(bool Read, bool Write)> AccessToServiceAccountAsync(Guid id, Guid userId,
|
||||
|
@ -0,0 +1,27 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Identity.IdentityServer;
|
||||
using Duende.IdentityServer.Models;
|
||||
|
||||
namespace Bit.MicroBenchmarks.Identity.IdentityServer;
|
||||
|
||||
public class StaticClientStoreTests
|
||||
{
|
||||
private readonly StaticClientStore _store;
|
||||
|
||||
public StaticClientStoreTests()
|
||||
{
|
||||
_store = new StaticClientStore(new GlobalSettings());
|
||||
}
|
||||
|
||||
[Params("mobile", "connector", "invalid", "a_much_longer_invalid_value_that_i_am_making_up", "WEB", "")]
|
||||
public string? ClientId { get; set; }
|
||||
|
||||
[Benchmark]
|
||||
public Client? TryGetValue()
|
||||
{
|
||||
return _store.ApiClients.TryGetValue(ClientId, out var client)
|
||||
? client
|
||||
: null;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
using Bit.Admin.Enums;
|
||||
using Bit.Admin.Models;
|
||||
using Bit.Admin.AdminConsole.Models;
|
||||
using Bit.Admin.Enums;
|
||||
using Bit.Admin.Services;
|
||||
using Bit.Admin.Utilities;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
@ -23,7 +23,7 @@ using Bit.Core.Vault.Repositories;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bit.Admin.Controllers;
|
||||
namespace Bit.Admin.AdminConsole.Controllers;
|
||||
|
||||
[Authorize]
|
||||
public class OrganizationsController : Controller
|
||||
@ -38,7 +38,6 @@ public class OrganizationsController : Controller
|
||||
private readonly IGroupRepository _groupRepository;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly ILicensingService _licensingService;
|
||||
private readonly IApplicationCacheService _applicationCacheService;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
@ -65,7 +64,6 @@ public class OrganizationsController : Controller
|
||||
IGroupRepository groupRepository,
|
||||
IPolicyRepository policyRepository,
|
||||
IPaymentService paymentService,
|
||||
ILicensingService licensingService,
|
||||
IApplicationCacheService applicationCacheService,
|
||||
GlobalSettings globalSettings,
|
||||
IReferenceEventService referenceEventService,
|
||||
@ -91,7 +89,6 @@ public class OrganizationsController : Controller
|
||||
_groupRepository = groupRepository;
|
||||
_policyRepository = policyRepository;
|
||||
_paymentService = paymentService;
|
||||
_licensingService = licensingService;
|
||||
_applicationCacheService = applicationCacheService;
|
||||
_globalSettings = globalSettings;
|
||||
_referenceEventService = referenceEventService;
|
@ -8,7 +8,7 @@ using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bit.Admin.Controllers;
|
||||
namespace Bit.Admin.AdminConsole.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[SelfHosted(NotSelfHostedOnly = true)]
|
@ -1,6 +1,7 @@
|
||||
using Bit.Admin.Enums;
|
||||
using Bit.Admin.Models;
|
||||
using Bit.Admin.AdminConsole.Models;
|
||||
using Bit.Admin.Enums;
|
||||
using Bit.Admin.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.Core.AdminConsole.Providers.Interfaces;
|
||||
@ -14,7 +15,7 @@ using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bit.Admin.Controllers;
|
||||
namespace Bit.Admin.AdminConsole.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[SelfHosted(NotSelfHostedOnly = true)]
|
||||
@ -31,6 +32,7 @@ public class ProvidersController : Controller
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly ICreateProviderCommand _createProviderCommand;
|
||||
private readonly IFeatureService _featureService;
|
||||
|
||||
public ProvidersController(
|
||||
IOrganizationRepository organizationRepository,
|
||||
@ -43,7 +45,8 @@ public class ProvidersController : Controller
|
||||
IApplicationCacheService applicationCacheService,
|
||||
IReferenceEventService referenceEventService,
|
||||
IUserService userService,
|
||||
ICreateProviderCommand createProviderCommand)
|
||||
ICreateProviderCommand createProviderCommand,
|
||||
IFeatureService featureService)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationService = organizationService;
|
||||
@ -56,6 +59,7 @@ public class ProvidersController : Controller
|
||||
_referenceEventService = referenceEventService;
|
||||
_userService = userService;
|
||||
_createProviderCommand = createProviderCommand;
|
||||
_featureService = featureService;
|
||||
}
|
||||
|
||||
[RequirePermission(Permission.Provider_List_View)]
|
||||
@ -236,7 +240,9 @@ public class ProvidersController : Controller
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
var organization = model.CreateOrganization(provider);
|
||||
var flexibleCollectionsSignupEnabled = _featureService.IsEnabled(FeatureFlagKeys.FlexibleCollectionsSignup);
|
||||
var flexibleCollectionsV1Enabled = _featureService.IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1);
|
||||
var organization = model.CreateOrganization(provider, flexibleCollectionsSignupEnabled, flexibleCollectionsV1Enabled);
|
||||
await _organizationService.CreatePendingOrganization(organization, model.Owners, User, _userService, model.SalesAssistedTrialStarted);
|
||||
await _providerService.AddOrganization(providerId, organization.Id, null);
|
||||
|
@ -3,7 +3,7 @@ using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.SharedWeb.Utilities;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class CreateProviderModel : IValidatableObject
|
||||
{
|
@ -11,7 +11,7 @@ using Bit.Core.Utilities;
|
||||
using Bit.Core.Vault.Entities;
|
||||
using Bit.SharedWeb.Utilities;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class OrganizationEditModel : OrganizationViewModel
|
||||
{
|
||||
@ -164,11 +164,22 @@ public class OrganizationEditModel : OrganizationViewModel
|
||||
{ "baseServiceAccount", p.SecretsManager.BaseServiceAccount }
|
||||
});
|
||||
|
||||
public Organization CreateOrganization(Provider provider)
|
||||
public Organization CreateOrganization(Provider provider, bool flexibleCollectionsSignupEnabled, bool flexibleCollectionsV1Enabled)
|
||||
{
|
||||
BillingEmail = provider.BillingEmail;
|
||||
|
||||
return ToOrganization(new Organization());
|
||||
var newOrg = new Organization
|
||||
{
|
||||
// This feature flag indicates that new organizations should be automatically onboarded to
|
||||
// Flexible Collections enhancements
|
||||
FlexibleCollections = flexibleCollectionsSignupEnabled,
|
||||
// These collection management settings smooth the migration for existing organizations by disabling some FC behavior.
|
||||
// If the organization is onboarded to Flexible Collections on signup, we turn them OFF to enable all new behaviour.
|
||||
// If the organization is NOT onboarded now, they will have to be migrated later, so they default to ON to limit FC changes on migration.
|
||||
LimitCollectionCreationDeletion = !flexibleCollectionsSignupEnabled,
|
||||
AllowAdminAccessToAllCollectionItems = !flexibleCollectionsV1Enabled
|
||||
};
|
||||
return ToOrganization(newOrg);
|
||||
}
|
||||
|
||||
public Organization ToOrganization(Organization existingOrganization)
|
@ -1,6 +1,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class OrganizationSelectableViewModel : Organization
|
||||
{
|
@ -1,6 +1,7 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Admin.Models;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class OrganizationUnassignedToProviderSearchViewModel : PagedModel<OrganizationSelectableViewModel>
|
||||
{
|
@ -5,15 +5,19 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Vault.Entities;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class OrganizationViewModel
|
||||
{
|
||||
public OrganizationViewModel() { }
|
||||
public OrganizationViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
public OrganizationViewModel(Organization org, Provider provider, IEnumerable<OrganizationConnection> connections,
|
||||
IEnumerable<OrganizationUserUserDetails> orgUsers, IEnumerable<Cipher> ciphers, IEnumerable<Collection> collections,
|
||||
IEnumerable<Group> groups, IEnumerable<Policy> policies, int secretsCount, int projectCount, int serviceAccountsCount,
|
||||
IEnumerable<OrganizationUserUserDetails> orgUsers, IEnumerable<Cipher> ciphers,
|
||||
IEnumerable<Collection> collections,
|
||||
IEnumerable<Group> groups, IEnumerable<Policy> policies, int secretsCount, int projectCount,
|
||||
int serviceAccountsCount,
|
||||
int occupiedSmSeatsCount)
|
||||
|
||||
{
|
||||
@ -34,12 +38,12 @@ public class OrganizationViewModel
|
||||
: OrganizationUserStatusType.Confirmed;
|
||||
Owners = string.Join(", ",
|
||||
orgUsers
|
||||
.Where(u => u.Type == OrganizationUserType.Owner && u.Status == organizationUserStatus)
|
||||
.Select(u => u.Email));
|
||||
.Where(u => u.Type == OrganizationUserType.Owner && u.Status == organizationUserStatus)
|
||||
.Select(u => u.Email));
|
||||
Admins = string.Join(", ",
|
||||
orgUsers
|
||||
.Where(u => u.Type == OrganizationUserType.Admin && u.Status == organizationUserStatus)
|
||||
.Select(u => u.Email));
|
||||
.Where(u => u.Type == OrganizationUserType.Admin && u.Status == organizationUserStatus)
|
||||
.Select(u => u.Email));
|
||||
SecretsCount = secretsCount;
|
||||
ProjectsCount = projectCount;
|
||||
ServiceAccountsCount = serviceAccountsCount;
|
||||
@ -65,4 +69,14 @@ public class OrganizationViewModel
|
||||
public int ServiceAccountsCount { get; set; }
|
||||
public int OccupiedSmSeatsCount { get; set; }
|
||||
public bool UseSecretsManager => Organization.UseSecretsManager;
|
||||
|
||||
public string GetCollectionManagementSetting(bool collectionManagementSetting)
|
||||
{
|
||||
if (!Organization.FlexibleCollections)
|
||||
{
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
return collectionManagementSetting ? "On" : "Off";
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Admin.Models;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class OrganizationsModel : PagedModel<Organization>
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.AdminConsole.Models.Data.Provider;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class ProviderEditModel : ProviderViewModel
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.Core.AdminConsole.Models.Data.Provider;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class ProviderViewModel
|
||||
{
|
@ -1,6 +1,7 @@
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Admin.Models;
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
|
||||
namespace Bit.Admin.Models;
|
||||
namespace Bit.Admin.AdminConsole.Models;
|
||||
|
||||
public class ProvidersModel : PagedModel<Provider>
|
||||
{
|
@ -1,3 +1,4 @@
|
||||
@using Bit.Core.Enums
|
||||
@model OrganizationViewModel
|
||||
<h2>Connections</h2>
|
||||
<div class="row">
|
||||
@ -49,7 +50,7 @@
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if(connection.Enabled)
|
||||
@if(connection.Enabled)
|
||||
{
|
||||
@if(@TempData["ConnectionActivated"] != null && @TempData["ConnectionActivated"].ToString() == @Model.Organization.Id.ToString())
|
||||
{
|
||||
@ -62,8 +63,8 @@
|
||||
{
|
||||
@if(connection.Type.Equals(OrganizationConnectionType.CloudBillingSync))
|
||||
{
|
||||
<a class="btn btn-outline-secondary btn-sm"
|
||||
data-id="@connection.Id" asp-controller="Organizations"
|
||||
<a class="btn btn-outline-secondary btn-sm"
|
||||
data-id="@connection.Id" asp-controller="Organizations"
|
||||
asp-action="TriggerBillingSync" asp-route-id="@Model.Organization.Id">
|
||||
Manually Sync
|
||||
</a>
|
||||
@ -78,4 +79,4 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,4 +1,6 @@
|
||||
@using Bit.Admin.Enums;
|
||||
@using Bit.Admin.Models
|
||||
@using Bit.Core.Enums
|
||||
@inject Bit.Admin.Services.IAccessControlService AccessControlService
|
||||
@model OrganizationEditModel
|
||||
@{
|
||||
@ -12,7 +14,7 @@
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
@await Html.PartialAsync("_OrganizationFormScripts")
|
||||
@await Html.PartialAsync("~/AdminConsole/Views/Shared/_OrganizationFormScripts.cshtml")
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
@ -77,7 +79,7 @@
|
||||
new BillingInformationModel { BillingInfo = Model.BillingInfo, OrganizationId = Model.Organization.Id, Entity = "Organization" })
|
||||
}
|
||||
|
||||
@await Html.PartialAsync("_OrganizationForm", Model)
|
||||
@await Html.PartialAsync("~/AdminConsole/Views/Shared/_OrganizationForm.cshtml", Model)
|
||||
|
||||
<div class="d-flex mt-4">
|
||||
<button type="submit" class="btn btn-primary" form="edit-form">Save</button>
|
@ -26,24 +26,6 @@
|
||||
<dt class="col-sm-4 col-lg-3">Using 2FA</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.Organization.TwoFactorIsEnabled() ? "Yes" : "No")</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Items</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@Model.CipherCount</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Collections</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@Model.CollectionCount</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Secrets</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.UseSecretsManager ? Model.SecretsCount: "N/A")</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Projects</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.UseSecretsManager ? Model.ProjectsCount: "N/A")</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Service Accounts</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.UseSecretsManager ? Model.ServiceAccountsCount: "N/A")</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Secrets Manager Seats</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.UseSecretsManager ? Model.OccupiedSmSeatsCount: "N/A" )</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Groups</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@Model.GroupCount</dd>
|
||||
|
||||
@ -59,3 +41,36 @@
|
||||
<dt class="col-sm-4 col-lg-3">Modified</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@Model.Organization.RevisionDate.ToString()</dd>
|
||||
</dl>
|
||||
|
||||
<h2>Password Manager</h2>
|
||||
<dl class="row">
|
||||
<dt class="col-sm-4 col-lg-3">Items</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@Model.CipherCount</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Collections</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@Model.CollectionCount</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Collection management enhancements</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.Organization.FlexibleCollections ? "On" : "Off")</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Administrators manage all collections</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.GetCollectionManagementSetting(Model.Organization.AllowAdminAccessToAllCollectionItems))</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Limit collection creation to administrators</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.GetCollectionManagementSetting(Model.Organization.LimitCollectionCreationDeletion))</dd>
|
||||
</dl>
|
||||
|
||||
<h2>Secrets Manager</h2>
|
||||
<dl class="row">
|
||||
<dt class="col-sm-4 col-lg-3">Secrets</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.UseSecretsManager ? Model.SecretsCount: "N/A")</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Projects</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.UseSecretsManager ? Model.ProjectsCount: "N/A")</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Service Accounts</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.UseSecretsManager ? Model.ServiceAccountsCount: "N/A")</dd>
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Secrets Manager Seats</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.UseSecretsManager ? Model.OccupiedSmSeatsCount: "N/A" )</dd>
|
||||
</dl>
|
@ -1,5 +1,4 @@
|
||||
@using Bit.SharedWeb.Utilities
|
||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@model OrganizationUnassignedToProviderSearchViewModel
|
||||
|
||||
@{
|
@ -38,7 +38,7 @@
|
||||
@admin.Status
|
||||
</td>
|
||||
<td>
|
||||
@if(admin.Status.Equals(ProviderUserStatusType.Confirmed)
|
||||
@if(admin.Status.Equals(ProviderUserStatusType.Confirmed)
|
||||
&& @Model.Provider.Status.Equals(ProviderStatusType.Pending)
|
||||
&& canResendEmailInvite)
|
||||
{
|
||||
@ -48,9 +48,9 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="btn btn-outline-secondary btn-sm"
|
||||
data-id="@admin.Id" asp-controller="Providers"
|
||||
asp-action="ResendInvite" asp-route-ownerId="@admin.UserId"
|
||||
<a class="btn btn-outline-secondary btn-sm"
|
||||
data-id="@admin.Id" asp-controller="Providers"
|
||||
asp-action="ResendInvite" asp-route-ownerId="@admin.UserId"
|
||||
asp-route-providerId="@Model.Provider.Id">
|
||||
Resend Setup Invite
|
||||
</a>
|
@ -4,7 +4,7 @@
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
@await Html.PartialAsync("_OrganizationFormScripts")
|
||||
@await Html.PartialAsync("~/AdminConsole/Views/Shared/_OrganizationFormScripts.cshtml")
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
<h1>New Client Organization</h1>
|
||||
|
||||
@await Html.PartialAsync("_OrganizationForm", Model)
|
||||
@await Html.PartialAsync("~/AdminConsole/Views/Shared/_OrganizationForm.cshtml", Model)
|
||||
<div class="d-flex mt-4">
|
||||
<button type="submit" class="btn btn-primary" form="edit-form">Save</button>
|
||||
<div class="ml-auto d-flex">
|
@ -1,6 +1,7 @@
|
||||
@using Bit.Core.AdminConsole.Enums.Provider
|
||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@using Bit.Admin.Enums
|
||||
@using Bit.Core.Enums
|
||||
@inject Bit.Admin.Services.IAccessControlService AccessControlService
|
||||
@model ProviderViewModel
|
||||
|
@ -7,13 +7,13 @@
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Status</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@Model.Provider.Status</dd>
|
||||
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Users</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.Provider.Type == ProviderType.Reseller ? "N/A" : Model.UserCount)</dd>
|
||||
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Provider Type</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@(Model.Provider.Type.GetDisplayAttribute()?.GetName())</dd>
|
||||
|
||||
|
||||
<dt class="col-sm-4 col-lg-3">Created</dt>
|
||||
<dd class="col-sm-8 col-lg-9">@Model.Provider.CreationDate.ToString()</dd>
|
||||
|
@ -1,6 +1,7 @@
|
||||
@using Bit.SharedWeb.Utilities
|
||||
@using Bit.Admin.Enums;
|
||||
@using Bit.Core.Enums
|
||||
@using Bit.Core.AdminConsole.Enums.Provider
|
||||
@using Bit.SharedWeb.Utilities
|
||||
@inject Bit.Admin.Services.IAccessControlService AccessControlService;
|
||||
|
||||
@model OrganizationEditModel
|
@ -1,5 +1,6 @@
|
||||
@inject IWebHostEnvironment HostingEnvironment
|
||||
@using Bit.Admin.Utilities
|
||||
@using Bit.Core.Enums
|
||||
@model OrganizationEditModel
|
||||
|
||||
<script>
|
5
src/Admin/AdminConsole/Views/_ViewImports.cshtml
Normal file
5
src/Admin/AdminConsole/Views/_ViewImports.cshtml
Normal file
@ -0,0 +1,5 @@
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Bit.Admin.AdminConsole
|
||||
@using Bit.Admin.AdminConsole.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@addTagHelper "*, Admin"
|
3
src/Admin/AdminConsole/Views/_ViewStart.cshtml
Normal file
3
src/Admin/AdminConsole/Views/_ViewStart.cshtml
Normal file
@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
@ -107,6 +107,7 @@ public class Startup
|
||||
services.Configure<RazorViewEngineOptions>(o =>
|
||||
{
|
||||
o.ViewLocationFormats.Add("/Auth/Views/{1}/{0}.cshtml");
|
||||
o.ViewLocationFormats.Add("/AdminConsole/Views/{1}/{0}.cshtml");
|
||||
});
|
||||
|
||||
// Jobs service
|
||||
|
@ -90,9 +90,12 @@
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<ul class="list-unstyled">
|
||||
<li><a href="https://github.com/bitwarden/server/releases" target="_blank">Check for Server updates</a></li>
|
||||
<li><a href="https://github.com/bitwarden/clients/releases" target="_blank">Check for Web updates</a></li>
|
||||
<li><a href="https://help.bitwarden.com/article/updating-on-premise/" target="_blank">How do I update?</a></li>
|
||||
<li><a href="https://github.com/bitwarden/server/releases" target="_blank" rel="noreferrer">Check for Server
|
||||
updates</a></li>
|
||||
<li><a href="https://github.com/bitwarden/clients/releases" target="_blank" rel="noreferrer">Check for Web
|
||||
updates</a></li>
|
||||
<li><a href="https://help.bitwarden.com/article/updating-on-premise/" target="_blank" rel="noreferrer">How
|
||||
do I update?</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,13 +24,14 @@
|
||||
{
|
||||
<tr>
|
||||
<td>@invoice.Date</td>
|
||||
<td><a target="_blank" href="@invoice.Url" title="View Invoice">@invoice.Number</a></td>
|
||||
<td><a target="_blank" rel="noreferrer" href="@invoice.Url" title="View Invoice">@invoice.Number</a>
|
||||
</td>
|
||||
<td>@invoice.Amount.ToString("C")</td>
|
||||
<td>@(invoice.Paid ? "Paid" : "Unpaid")</td>
|
||||
@if (canDownloadInvoice)
|
||||
{
|
||||
<td>
|
||||
<a target="_blank" href="@invoice.PdfUrl" title="Download Invoice">
|
||||
<a target="_blank" rel="noreferrer" href="@invoice.PdfUrl" title="Download Invoice">
|
||||
<i class="fa fa-file-pdf-o"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
@ -125,7 +125,8 @@
|
||||
@if (GlobalSettings.SelfHosted)
|
||||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://help.bitwarden.com/hosting/" target="_blank">Docs</a>
|
||||
<a class="nav-link" href="https://help.bitwarden.com/hosting/" target="_blank"
|
||||
rel="noreferrer">Docs</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
@ -226,7 +226,7 @@ public class OrganizationUsersController : Controller
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
|
||||
await _organizationService.InitPendingOrganization(user.Id, orgId, model.Keys.PublicKey, model.Keys.EncryptedPrivateKey, model.CollectionName);
|
||||
await _organizationService.InitPendingOrganization(user.Id, orgId, organizationUserId, model.Keys.PublicKey, model.Keys.EncryptedPrivateKey, model.CollectionName);
|
||||
await _acceptOrgUserCommand.AcceptOrgUserByEmailTokenAsync(organizationUserId, user, model.Token, _userService);
|
||||
await _organizationService.ConfirmUserAsync(orgId, organizationUserId, model.Key, user.Id, _userService);
|
||||
}
|
||||
|
@ -464,50 +464,52 @@ public class OrganizationsController : Controller
|
||||
await _organizationService.VerifyBankAsync(orgIdGuid, model.Amount1.Value, model.Amount2.Value);
|
||||
}
|
||||
|
||||
[HttpPost("{id}/cancel")]
|
||||
[SelfHosted(NotSelfHostedOnly = true)]
|
||||
public async Task PostCancel(Guid id, [FromBody] SubscriptionCancellationRequestModel request)
|
||||
[HttpPost("{id}/churn")]
|
||||
public async Task PostChurn(Guid id, [FromBody] SubscriptionCancellationRequestModel request)
|
||||
{
|
||||
if (!await _currentContext.EditSubscription(id))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var presentUserWithOffboardingSurvey =
|
||||
_featureService.IsEnabled(FeatureFlagKeys.AC1607_PresentUsersWithOffboardingSurvey);
|
||||
var organization = await _organizationRepository.GetByIdAsync(id);
|
||||
|
||||
if (presentUserWithOffboardingSurvey)
|
||||
if (organization == null)
|
||||
{
|
||||
var organization = await _organizationRepository.GetByIdAsync(id);
|
||||
|
||||
if (organization == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var subscription = await _getSubscriptionQuery.GetSubscription(organization);
|
||||
|
||||
await _cancelSubscriptionCommand.CancelSubscription(subscription,
|
||||
new OffboardingSurveyResponse
|
||||
{
|
||||
UserId = _currentContext.UserId!.Value,
|
||||
Reason = request.Reason,
|
||||
Feedback = request.Feedback
|
||||
},
|
||||
organization.IsExpired());
|
||||
|
||||
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(
|
||||
ReferenceEventType.CancelSubscription,
|
||||
organization,
|
||||
_currentContext)
|
||||
{
|
||||
EndOfPeriod = organization.IsExpired()
|
||||
});
|
||||
throw new NotFoundException();
|
||||
}
|
||||
else
|
||||
|
||||
var subscription = await _getSubscriptionQuery.GetSubscription(organization);
|
||||
|
||||
await _cancelSubscriptionCommand.CancelSubscription(subscription,
|
||||
new OffboardingSurveyResponse
|
||||
{
|
||||
UserId = _currentContext.UserId!.Value,
|
||||
Reason = request.Reason,
|
||||
Feedback = request.Feedback
|
||||
},
|
||||
organization.IsExpired());
|
||||
|
||||
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(
|
||||
ReferenceEventType.CancelSubscription,
|
||||
organization,
|
||||
_currentContext)
|
||||
{
|
||||
await _organizationService.CancelSubscriptionAsync(id);
|
||||
EndOfPeriod = organization.IsExpired()
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("{id}/cancel")]
|
||||
[SelfHosted(NotSelfHostedOnly = true)]
|
||||
public async Task PostCancel(string id)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.EditSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
await _organizationService.CancelSubscriptionAsync(orgIdGuid);
|
||||
}
|
||||
|
||||
[HttpPost("{id}/reinstate")]
|
||||
|
@ -821,9 +821,8 @@ public class AccountsController : Controller
|
||||
await _userService.UpdateLicenseAsync(user, license);
|
||||
}
|
||||
|
||||
[HttpPost("cancel-premium")]
|
||||
[SelfHosted(NotSelfHostedOnly = true)]
|
||||
public async Task PostCancel([FromBody] SubscriptionCancellationRequestModel request)
|
||||
[HttpPost("churn-premium")]
|
||||
public async Task PostChurn([FromBody] SubscriptionCancellationRequestModel request)
|
||||
{
|
||||
var user = await _userService.GetUserByPrincipalAsync(User);
|
||||
|
||||
@ -832,34 +831,37 @@ public class AccountsController : Controller
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
|
||||
var presentUserWithOffboardingSurvey =
|
||||
_featureService.IsEnabled(FeatureFlagKeys.AC1607_PresentUsersWithOffboardingSurvey);
|
||||
var subscription = await _getSubscriptionQuery.GetSubscription(user);
|
||||
|
||||
if (presentUserWithOffboardingSurvey)
|
||||
{
|
||||
var subscription = await _getSubscriptionQuery.GetSubscription(user);
|
||||
|
||||
await _cancelSubscriptionCommand.CancelSubscription(subscription,
|
||||
new OffboardingSurveyResponse
|
||||
{
|
||||
UserId = user.Id,
|
||||
Reason = request.Reason,
|
||||
Feedback = request.Feedback
|
||||
},
|
||||
user.IsExpired());
|
||||
|
||||
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(
|
||||
ReferenceEventType.CancelSubscription,
|
||||
user,
|
||||
_currentContext)
|
||||
await _cancelSubscriptionCommand.CancelSubscription(subscription,
|
||||
new OffboardingSurveyResponse
|
||||
{
|
||||
EndOfPeriod = user.IsExpired()
|
||||
});
|
||||
}
|
||||
else
|
||||
UserId = user.Id,
|
||||
Reason = request.Reason,
|
||||
Feedback = request.Feedback
|
||||
},
|
||||
user.IsExpired());
|
||||
|
||||
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(
|
||||
ReferenceEventType.CancelSubscription,
|
||||
user,
|
||||
_currentContext)
|
||||
{
|
||||
await _userService.CancelPremiumAsync(user);
|
||||
EndOfPeriod = user.IsExpired()
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("cancel-premium")]
|
||||
[SelfHosted(NotSelfHostedOnly = true)]
|
||||
public async Task PostCancel()
|
||||
{
|
||||
var user = await _userService.GetUserByPrincipalAsync(User);
|
||||
if (user == null)
|
||||
{
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
|
||||
await _userService.CancelPremiumAsync(user);
|
||||
}
|
||||
|
||||
[HttpPost("reinstate-premium")]
|
||||
|
@ -44,13 +44,11 @@ public class CiphersController : Controller
|
||||
private readonly Version _cipherKeyEncryptionMinimumVersion = new Version(Constants.CipherKeyEncryptionMinimumVersion);
|
||||
private readonly IFeatureService _featureService;
|
||||
private readonly IOrganizationCiphersQuery _organizationCiphersQuery;
|
||||
private readonly IApplicationCacheService _applicationCacheService;
|
||||
|
||||
private bool UseFlexibleCollections =>
|
||||
_featureService.IsEnabled(FeatureFlagKeys.FlexibleCollections);
|
||||
|
||||
private bool UseFlexibleCollectionsV1 =>
|
||||
_featureService.IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1);
|
||||
|
||||
public CiphersController(
|
||||
ICipherRepository cipherRepository,
|
||||
ICollectionCipherRepository collectionCipherRepository,
|
||||
@ -62,7 +60,8 @@ public class CiphersController : Controller
|
||||
ILogger<CiphersController> logger,
|
||||
GlobalSettings globalSettings,
|
||||
IFeatureService featureService,
|
||||
IOrganizationCiphersQuery organizationCiphersQuery)
|
||||
IOrganizationCiphersQuery organizationCiphersQuery,
|
||||
IApplicationCacheService applicationCacheService)
|
||||
{
|
||||
_cipherRepository = cipherRepository;
|
||||
_collectionCipherRepository = collectionCipherRepository;
|
||||
@ -75,6 +74,7 @@ public class CiphersController : Controller
|
||||
_globalSettings = globalSettings;
|
||||
_featureService = featureService;
|
||||
_organizationCiphersQuery = organizationCiphersQuery;
|
||||
_applicationCacheService = applicationCacheService;
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
@ -241,7 +241,7 @@ public class CiphersController : Controller
|
||||
public async Task<ListResponseModel<CipherMiniDetailsResponseModel>> GetOrganizationCiphers(Guid organizationId)
|
||||
{
|
||||
// Flexible Collections Logic
|
||||
if (UseFlexibleCollectionsV1)
|
||||
if (await UseFlexibleCollectionsV1Async(organizationId))
|
||||
{
|
||||
return await GetAllOrganizationCiphersAsync(organizationId);
|
||||
}
|
||||
@ -266,7 +266,7 @@ public class CiphersController : Controller
|
||||
[HttpGet("organization-details/assigned")]
|
||||
public async Task<ListResponseModel<CipherDetailsResponseModel>> GetAssignedOrganizationCiphers(Guid organizationId)
|
||||
{
|
||||
if (!UseFlexibleCollectionsV1)
|
||||
if (!await UseFlexibleCollectionsV1Async(organizationId))
|
||||
{
|
||||
throw new FeatureUnavailableException();
|
||||
}
|
||||
@ -322,9 +322,13 @@ public class CiphersController : Controller
|
||||
{
|
||||
var org = _currentContext.GetOrganization(organizationId);
|
||||
|
||||
// We do NOT need to check the organization collection management setting here because Owners/Admins can
|
||||
// ALWAYS access all ciphers in order to export them. Additionally, custom users with AccessImportExport or
|
||||
// EditAnyCollection permissions can also always access all ciphers.
|
||||
if (org is
|
||||
{ Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or
|
||||
{ Permissions.AccessImportExport: true })
|
||||
{ Permissions.AccessImportExport: true } or
|
||||
{ Permissions.EditAnyCollection: true })
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -974,4 +978,15 @@ public class CiphersController : Controller
|
||||
{
|
||||
return await _cipherRepository.GetByIdAsync(cipherId, userId, UseFlexibleCollections);
|
||||
}
|
||||
|
||||
private async Task<bool> UseFlexibleCollectionsV1Async(Guid organizationId)
|
||||
{
|
||||
if (!_featureService.IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var organizationAbility = await _applicationCacheService.GetOrganizationAbilityAsync(organizationId);
|
||||
return organizationAbility?.FlexibleCollections ?? false;
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using Bit.Core.Jobs;
|
||||
using Bit.Core.Settings;
|
||||
using Quartz;
|
||||
|
||||
namespace Bit.Billing.Jobs;
|
||||
|
||||
public class JobsHostedService : BaseJobsHostedService
|
||||
{
|
||||
public JobsHostedService(
|
||||
GlobalSettings globalSettings,
|
||||
IServiceProvider serviceProvider,
|
||||
ILogger<JobsHostedService> logger,
|
||||
ILogger<JobListener> listenerLogger)
|
||||
: base(globalSettings, serviceProvider, logger, listenerLogger) { }
|
||||
|
||||
public override async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var timeZone = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
|
||||
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") :
|
||||
TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
|
||||
if (_globalSettings.SelfHosted)
|
||||
{
|
||||
timeZone = TimeZoneInfo.Local;
|
||||
}
|
||||
|
||||
var everyDayAtNinePmTrigger = TriggerBuilder.Create()
|
||||
.WithIdentity("EveryDayAtNinePmTrigger")
|
||||
.StartNow()
|
||||
.WithCronSchedule("0 0 21 * * ?", x => x.InTimeZone(timeZone))
|
||||
.Build();
|
||||
|
||||
Jobs = new List<Tuple<Type, ITrigger>>();
|
||||
|
||||
// Add jobs here
|
||||
|
||||
await base.StartAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public static void AddJobsServices(IServiceCollection services)
|
||||
{
|
||||
// Register jobs here
|
||||
}
|
||||
}
|
@ -76,10 +76,6 @@ public class Startup
|
||||
// Authentication
|
||||
services.AddAuthentication();
|
||||
|
||||
// Jobs service, uncomment when we have some jobs to run
|
||||
// Jobs.JobsHostedService.AddJobsServices(services);
|
||||
// services.AddHostedService<Jobs.JobsHostedService>();
|
||||
|
||||
// Set up HttpClients
|
||||
services.AddHttpClient("FreshdeskApi");
|
||||
|
||||
|
@ -84,7 +84,7 @@ public interface IOrganizationService
|
||||
/// <remarks>
|
||||
/// This method must target a disabled Organization that has null keys and status as 'Pending'.
|
||||
/// </remarks>
|
||||
Task InitPendingOrganization(Guid userId, Guid organizationId, string publicKey, string privateKey, string collectionName);
|
||||
Task InitPendingOrganization(Guid userId, Guid organizationId, Guid organizationUserId, string publicKey, string privateKey, string collectionName);
|
||||
Task ReplaceAndUpdateCacheAsync(Organization org, EventType? orgEvent = null);
|
||||
|
||||
void ValidatePasswordManagerPlan(Models.StaticStore.Plan plan, OrganizationUpgrade upgrade);
|
||||
|
@ -2526,7 +2526,7 @@ public class OrganizationService : IOrganizationService
|
||||
});
|
||||
}
|
||||
|
||||
public async Task InitPendingOrganization(Guid userId, Guid organizationId, string publicKey, string privateKey, string collectionName)
|
||||
public async Task InitPendingOrganization(Guid userId, Guid organizationId, Guid organizationUserId, string publicKey, string privateKey, string collectionName)
|
||||
{
|
||||
await ValidateSignUpPoliciesAsync(userId);
|
||||
|
||||
@ -2565,9 +2565,8 @@ public class OrganizationService : IOrganizationService
|
||||
List<CollectionAccessSelection> defaultOwnerAccess = null;
|
||||
if (org.FlexibleCollections)
|
||||
{
|
||||
var orgUser = await _organizationUserRepository.GetByOrganizationAsync(org.Id, userId);
|
||||
defaultOwnerAccess =
|
||||
[new CollectionAccessSelection { Id = orgUser.Id, HidePasswords = false, ReadOnly = false, Manage = true }];
|
||||
[new CollectionAccessSelection { Id = organizationUserId, HidePasswords = false, ReadOnly = false, Manage = true }];
|
||||
}
|
||||
|
||||
var defaultCollection = new Collection
|
||||
|
@ -147,7 +147,8 @@ public static class FeatureFlagKeys
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ TrustedDeviceEncryption, "true" },
|
||||
{ Fido2VaultCredentials, "true" }
|
||||
{ Fido2VaultCredentials, "true" },
|
||||
{ DuoRedirect, "true" }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCoreRateLimit.Redis" Version="2.0.0" />
|
||||
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.300.51" />
|
||||
<PackageReference Include="AWSSDK.SQS" Version="3.7.300.51" />
|
||||
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.300.52" />
|
||||
<PackageReference Include="AWSSDK.SQS" Version="3.7.300.52" />
|
||||
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.3.2" />
|
||||
<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.15.0" />
|
||||
<PackageReference Include="Azure.Storage.Blobs" Version="12.14.1" />
|
||||
@ -43,7 +43,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="6.0.25" />
|
||||
<PackageReference Include="Quartz" Version="3.4.0" />
|
||||
<PackageReference Include="SendGrid" Version="9.29.1" />
|
||||
<PackageReference Include="SendGrid" Version="9.29.2" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
|
||||
|
@ -38,6 +38,14 @@ public class UserServiceAccountAccessPolicy : BaseAccessPolicy
|
||||
public ServiceAccount? GrantedServiceAccount { get; set; }
|
||||
}
|
||||
|
||||
public class UserSecretAccessPolicy : BaseAccessPolicy
|
||||
{
|
||||
public Guid? OrganizationUserId { get; set; }
|
||||
public User? User { get; set; }
|
||||
public Guid? GrantedSecretId { get; set; }
|
||||
public Secret? GrantedSecret { get; set; }
|
||||
}
|
||||
|
||||
public class GroupProjectAccessPolicy : BaseAccessPolicy
|
||||
{
|
||||
public Guid? GroupId { get; set; }
|
||||
@ -56,6 +64,15 @@ public class GroupServiceAccountAccessPolicy : BaseAccessPolicy
|
||||
public ServiceAccount? GrantedServiceAccount { get; set; }
|
||||
}
|
||||
|
||||
public class GroupSecretAccessPolicy : BaseAccessPolicy
|
||||
{
|
||||
public Guid? GroupId { get; set; }
|
||||
public Group? Group { get; set; }
|
||||
public bool? CurrentUserInGroup { get; set; }
|
||||
public Guid? GrantedSecretId { get; set; }
|
||||
public Secret? GrantedSecret { get; set; }
|
||||
}
|
||||
|
||||
public class ServiceAccountProjectAccessPolicy : BaseAccessPolicy
|
||||
{
|
||||
public Guid? ServiceAccountId { get; set; }
|
||||
@ -63,3 +80,11 @@ public class ServiceAccountProjectAccessPolicy : BaseAccessPolicy
|
||||
public Guid? GrantedProjectId { get; set; }
|
||||
public Project? GrantedProject { get; set; }
|
||||
}
|
||||
|
||||
public class ServiceAccountSecretAccessPolicy : BaseAccessPolicy
|
||||
{
|
||||
public Guid? ServiceAccountId { get; set; }
|
||||
public ServiceAccount? ServiceAccount { get; set; }
|
||||
public Guid? GrantedSecretId { get; set; }
|
||||
public Secret? GrantedSecret { get; set; }
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Buffers;
|
||||
using System.Buffers.Text;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
@ -88,7 +88,7 @@ public class EncryptedStringAttribute : ValidationAttribute
|
||||
}
|
||||
|
||||
// Simply cast the number to the enum, this could be a value that doesn't actually have a backing enum
|
||||
// entry but that is alright we will use it to look in the dictionary and non-valid
|
||||
// entry but that is alright we will use it to look in the dictionary and non-valid
|
||||
// numbers will be filtered out there.
|
||||
encryptionType = (EncryptionType)encryptionTypeNumber;
|
||||
|
||||
@ -110,7 +110,7 @@ public class EncryptedStringAttribute : ValidationAttribute
|
||||
if (requiredPieces == 1)
|
||||
{
|
||||
// Only one more part is needed so don't split and check the chunk
|
||||
if (!IsValidBase64(rest))
|
||||
if (rest.IsEmpty || !Base64.IsValid(rest))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -127,7 +127,7 @@ public class EncryptedStringAttribute : ValidationAttribute
|
||||
}
|
||||
|
||||
// Is the required chunk valid base 64?
|
||||
if (!IsValidBase64(chunk))
|
||||
if (chunk.IsEmpty || !Base64.IsValid(chunk))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -140,37 +140,4 @@ public class EncryptedStringAttribute : ValidationAttribute
|
||||
// No more parts are required, so check there are no extra parts
|
||||
return rest.IndexOf('|') == -1;
|
||||
}
|
||||
|
||||
private static bool IsValidBase64(ReadOnlySpan<char> input)
|
||||
{
|
||||
const int StackLimit = 256;
|
||||
|
||||
byte[]? pooledChunks = null;
|
||||
|
||||
var upperLimitLength = CalculateBase64ByteLengthUpperLimit(input.Length);
|
||||
|
||||
// Ref: https://vcsjones.dev/stackalloc/
|
||||
var byteBuffer = upperLimitLength > StackLimit
|
||||
? (pooledChunks = ArrayPool<byte>.Shared.Rent(upperLimitLength))
|
||||
: stackalloc byte[StackLimit];
|
||||
|
||||
try
|
||||
{
|
||||
var successful = Convert.TryFromBase64Chars(input, byteBuffer, out var bytesWritten);
|
||||
return successful && bytesWritten > 0;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Check if we rented the pool and if so, return it.
|
||||
if (pooledChunks != null)
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(pooledChunks, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static int CalculateBase64ByteLengthUpperLimit(int charLength)
|
||||
{
|
||||
return 3 * (charLength / 4);
|
||||
}
|
||||
}
|
||||
|
@ -80,9 +80,9 @@ public class ClientStore : IClientStore
|
||||
return await CreateUserClientAsync(clientId);
|
||||
}
|
||||
|
||||
if (_staticClientStore.ApiClients.ContainsKey(clientId))
|
||||
if (_staticClientStore.ApiClients.TryGetValue(clientId, out var client))
|
||||
{
|
||||
return _staticClientStore.ApiClients[clientId];
|
||||
return client;
|
||||
}
|
||||
|
||||
return await CreateApiKeyClientAsync(clientId);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Bit.Core.Enums;
|
||||
using System.Collections.Frozen;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Settings;
|
||||
using Duende.IdentityServer.Models;
|
||||
|
||||
@ -16,8 +17,8 @@ public class StaticClientStore
|
||||
new ApiClient(globalSettings, BitwardenClient.Desktop, 30, 1),
|
||||
new ApiClient(globalSettings, BitwardenClient.Cli, 30, 1),
|
||||
new ApiClient(globalSettings, BitwardenClient.DirectoryConnector, 30, 24)
|
||||
}.ToDictionary(c => c.ClientId);
|
||||
}.ToFrozenDictionary(c => c.ClientId);
|
||||
}
|
||||
|
||||
public IDictionary<string, Client> ApiClients { get; private set; }
|
||||
public FrozenDictionary<string, Client> ApiClients { get; }
|
||||
}
|
||||
|
@ -180,6 +180,8 @@ public class OrganizationRepository : Repository<Core.AdminConsole.Entities.Orga
|
||||
.ExecuteDeleteAsync();
|
||||
await dbContext.UserServiceAccountAccessPolicy.Where(ap => ap.OrganizationUser.OrganizationId == organization.Id)
|
||||
.ExecuteDeleteAsync();
|
||||
await dbContext.UserSecretAccessPolicy.Where(ap => ap.OrganizationUser.OrganizationId == organization.Id)
|
||||
.ExecuteDeleteAsync();
|
||||
await dbContext.OrganizationUsers.Where(ou => ou.OrganizationId == organization.Id)
|
||||
.ExecuteDeleteAsync();
|
||||
await dbContext.ProviderOrganizations.Where(po => po.OrganizationId == organization.Id)
|
||||
|
@ -100,6 +100,8 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
|
||||
dbContext.UserProjectAccessPolicy.Where(ap => ap.OrganizationUserId == organizationUserId));
|
||||
dbContext.UserServiceAccountAccessPolicy.RemoveRange(
|
||||
dbContext.UserServiceAccountAccessPolicy.Where(ap => ap.OrganizationUserId == organizationUserId));
|
||||
dbContext.UserSecretAccessPolicy.RemoveRange(
|
||||
dbContext.UserSecretAccessPolicy.Where(ap => ap.OrganizationUserId == organizationUserId));
|
||||
|
||||
var orgSponsorships = await dbContext.OrganizationSponsorships
|
||||
.Where(os => os.SponsoringOrganizationUserId == organizationUserId)
|
||||
@ -117,18 +119,36 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
|
||||
|
||||
public async Task DeleteManyAsync(IEnumerable<Guid> organizationUserIds)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
await dbContext.UserBumpAccountRevisionDateByOrganizationUserIdsAsync(organizationUserIds);
|
||||
var entities = await dbContext.OrganizationUsers
|
||||
// TODO: Does this work?
|
||||
.Where(ou => organizationUserIds.Contains(ou.Id))
|
||||
.ToListAsync();
|
||||
var targetOrganizationUserIds = organizationUserIds.ToList();
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
|
||||
dbContext.OrganizationUsers.RemoveRange(entities);
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
var transaction = await dbContext.Database.BeginTransactionAsync();
|
||||
await dbContext.UserBumpAccountRevisionDateByOrganizationUserIdsAsync(targetOrganizationUserIds);
|
||||
|
||||
await dbContext.CollectionUsers
|
||||
.Where(cu => targetOrganizationUserIds.Contains(cu.OrganizationUserId))
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
await dbContext.GroupUsers
|
||||
.Where(gu => targetOrganizationUserIds.Contains(gu.OrganizationUserId))
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
await dbContext.UserProjectAccessPolicy
|
||||
.Where(ap => targetOrganizationUserIds.Contains(ap.OrganizationUserId!.Value))
|
||||
.ExecuteDeleteAsync();
|
||||
await dbContext.UserServiceAccountAccessPolicy
|
||||
.Where(ap => targetOrganizationUserIds.Contains(ap.OrganizationUserId!.Value))
|
||||
.ExecuteDeleteAsync();
|
||||
await dbContext.UserSecretAccessPolicy
|
||||
.Where(ap => targetOrganizationUserIds.Contains(ap.OrganizationUserId!.Value))
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
await dbContext.OrganizationUsers
|
||||
.Where(ou => targetOrganizationUserIds.Contains(ou.Id)).ExecuteDeleteAsync();
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
|
||||
public async Task<Tuple<Core.Entities.OrganizationUser, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id)
|
||||
|
@ -13,10 +13,6 @@ public class GrantEntityTypeConfiguration : IEntityTypeConfiguration<Grant>
|
||||
.HasName("PK_Grant")
|
||||
.IsClustered();
|
||||
|
||||
builder
|
||||
.Property(s => s.Id)
|
||||
.UseIdentityColumn();
|
||||
|
||||
builder
|
||||
.HasIndex(s => s.Key)
|
||||
.IsUnique(true);
|
||||
|
@ -3,9 +3,9 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||
<PackageReference Include="linq2db" Version="5.3.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.15" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.15" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.15" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.16" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.11" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
|
||||
<PackageReference Include="linq2db.EntityFrameworkCore" Version="7.6.0" />
|
||||
|
@ -27,6 +27,9 @@ public class DatabaseContext : DbContext
|
||||
public DbSet<ServiceAccountProjectAccessPolicy> ServiceAccountProjectAccessPolicy { get; set; }
|
||||
public DbSet<UserServiceAccountAccessPolicy> UserServiceAccountAccessPolicy { get; set; }
|
||||
public DbSet<GroupServiceAccountAccessPolicy> GroupServiceAccountAccessPolicy { get; set; }
|
||||
public DbSet<UserSecretAccessPolicy> UserSecretAccessPolicy { get; set; }
|
||||
public DbSet<GroupSecretAccessPolicy> GroupSecretAccessPolicy { get; set; }
|
||||
public DbSet<ServiceAccountSecretAccessPolicy> ServiceAccountSecretAccessPolicy { get; set; }
|
||||
public DbSet<ApiKey> ApiKeys { get; set; }
|
||||
public DbSet<Cipher> Ciphers { get; set; }
|
||||
public DbSet<Collection> Collections { get; set; }
|
||||
|
@ -13,9 +13,12 @@ public class AccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<Acce
|
||||
.HasDiscriminator<string>("Discriminator")
|
||||
.HasValue<UserProjectAccessPolicy>(AccessPolicyDiscriminator.UserProject)
|
||||
.HasValue<UserServiceAccountAccessPolicy>(AccessPolicyDiscriminator.UserServiceAccount)
|
||||
.HasValue<UserSecretAccessPolicy>(AccessPolicyDiscriminator.UserSecret)
|
||||
.HasValue<GroupProjectAccessPolicy>(AccessPolicyDiscriminator.GroupProject)
|
||||
.HasValue<GroupServiceAccountAccessPolicy>(AccessPolicyDiscriminator.GroupServiceAccount)
|
||||
.HasValue<ServiceAccountProjectAccessPolicy>(AccessPolicyDiscriminator.ServiceAccountProject);
|
||||
.HasValue<GroupSecretAccessPolicy>(AccessPolicyDiscriminator.GroupSecret)
|
||||
.HasValue<ServiceAccountProjectAccessPolicy>(AccessPolicyDiscriminator.ServiceAccountProject)
|
||||
.HasValue<ServiceAccountSecretAccessPolicy>(AccessPolicyDiscriminator.ServiceAccountSecret);
|
||||
|
||||
builder
|
||||
.Property(s => s.Id)
|
||||
@ -63,6 +66,26 @@ public class UserServiceAccountAccessPolicyEntityTypeConfiguration : IEntityType
|
||||
}
|
||||
}
|
||||
|
||||
public class UserSecretAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<UserSecretAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UserSecretAccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.Property(e => e.OrganizationUserId)
|
||||
.HasColumnName(nameof(UserSecretAccessPolicy.OrganizationUserId));
|
||||
|
||||
builder
|
||||
.Property(e => e.GrantedSecretId)
|
||||
.HasColumnName(nameof(UserSecretAccessPolicy.GrantedSecretId));
|
||||
|
||||
builder
|
||||
.HasOne(e => e.GrantedSecret)
|
||||
.WithMany(e => e.UserAccessPolicies)
|
||||
.HasForeignKey(nameof(UserSecretAccessPolicy.GrantedSecretId))
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupProjectAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<GroupProjectAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GroupProjectAccessPolicy> builder)
|
||||
@ -109,6 +132,32 @@ public class GroupServiceAccountAccessPolicyEntityTypeConfiguration : IEntityTyp
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupSecretAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<GroupSecretAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GroupSecretAccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.Property(e => e.GroupId)
|
||||
.HasColumnName(nameof(GroupSecretAccessPolicy.GroupId));
|
||||
|
||||
builder
|
||||
.Property(e => e.GrantedSecretId)
|
||||
.HasColumnName(nameof(GroupSecretAccessPolicy.GrantedSecretId));
|
||||
|
||||
builder
|
||||
.HasOne(e => e.GrantedSecret)
|
||||
.WithMany(e => e.GroupAccessPolicies)
|
||||
.HasForeignKey(nameof(GroupSecretAccessPolicy.GrantedSecretId))
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder
|
||||
.HasOne(e => e.Group)
|
||||
.WithMany()
|
||||
.HasForeignKey(nameof(GroupSecretAccessPolicy.GroupId))
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
|
||||
public class ServiceAccountProjectAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<ServiceAccountProjectAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ServiceAccountProjectAccessPolicy> builder)
|
||||
@ -128,3 +177,23 @@ public class ServiceAccountProjectAccessPolicyEntityTypeConfiguration : IEntityT
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
|
||||
public class ServiceAccountSecretAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<ServiceAccountSecretAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ServiceAccountSecretAccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.Property(e => e.ServiceAccountId)
|
||||
.HasColumnName(nameof(ServiceAccountSecretAccessPolicy.ServiceAccountId));
|
||||
|
||||
builder
|
||||
.Property(e => e.GrantedSecretId)
|
||||
.HasColumnName(nameof(ServiceAccountSecretAccessPolicy.GrantedSecretId));
|
||||
|
||||
builder
|
||||
.HasOne(e => e.GrantedSecret)
|
||||
.WithMany(e => e.ServiceAccountAccessPolicies)
|
||||
.HasForeignKey(nameof(ServiceAccountSecretAccessPolicy.GrantedSecretId))
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,10 @@ public static class AccessPolicyDiscriminator
|
||||
{
|
||||
public const string UserProject = "user_project";
|
||||
public const string UserServiceAccount = "user_service_account";
|
||||
public const string UserSecret = "user_secret";
|
||||
public const string GroupProject = "group_project";
|
||||
public const string GroupServiceAccount = "group_service_account";
|
||||
public const string GroupSecret = "group_secret";
|
||||
public const string ServiceAccountProject = "service_account_project";
|
||||
|
||||
public const string ServiceAccountSecret = "service_account_secret";
|
||||
}
|
||||
|
@ -24,6 +24,12 @@ public class AccessPolicyMapperProfile : Profile
|
||||
.ReverseMap()
|
||||
.ForMember(dst => dst.User, opt => opt.MapFrom(src => src.OrganizationUser.User));
|
||||
|
||||
CreateMap<Core.SecretsManager.Entities.UserSecretAccessPolicy, UserSecretAccessPolicy>()
|
||||
.ForMember(dst => dst.GrantedSecret, opt => opt.Ignore())
|
||||
.ForMember(dst => dst.OrganizationUser, opt => opt.Ignore())
|
||||
.ReverseMap()
|
||||
.ForMember(dst => dst.User, opt => opt.MapFrom(src => src.OrganizationUser.User));
|
||||
|
||||
CreateMap<Core.SecretsManager.Entities.GroupProjectAccessPolicy, GroupProjectAccessPolicy>()
|
||||
.ForMember(dst => dst.GrantedProject, opt => opt.Ignore())
|
||||
.ForMember(dst => dst.Group, opt => opt.Ignore())
|
||||
@ -34,10 +40,20 @@ public class AccessPolicyMapperProfile : Profile
|
||||
.ForMember(dst => dst.Group, opt => opt.Ignore())
|
||||
.ReverseMap();
|
||||
|
||||
CreateMap<Core.SecretsManager.Entities.GroupSecretAccessPolicy, GroupSecretAccessPolicy>()
|
||||
.ForMember(dst => dst.GrantedSecret, opt => opt.Ignore())
|
||||
.ForMember(dst => dst.Group, opt => opt.Ignore())
|
||||
.ReverseMap();
|
||||
|
||||
CreateMap<Core.SecretsManager.Entities.ServiceAccountProjectAccessPolicy, ServiceAccountProjectAccessPolicy>()
|
||||
.ForMember(dst => dst.GrantedProject, opt => opt.Ignore())
|
||||
.ForMember(dst => dst.ServiceAccount, opt => opt.Ignore())
|
||||
.ReverseMap();
|
||||
|
||||
CreateMap<Core.SecretsManager.Entities.ServiceAccountSecretAccessPolicy, ServiceAccountSecretAccessPolicy>()
|
||||
.ForMember(dst => dst.GrantedSecret, opt => opt.Ignore())
|
||||
.ForMember(dst => dst.ServiceAccount, opt => opt.Ignore())
|
||||
.ReverseMap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,6 +77,14 @@ public class UserServiceAccountAccessPolicy : AccessPolicy
|
||||
public virtual ServiceAccount GrantedServiceAccount { get; set; }
|
||||
}
|
||||
|
||||
public class UserSecretAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? OrganizationUserId { get; set; }
|
||||
public virtual OrganizationUser OrganizationUser { get; set; }
|
||||
public Guid? GrantedSecretId { get; set; }
|
||||
public virtual Secret GrantedSecret { get; set; }
|
||||
}
|
||||
|
||||
public class GroupProjectAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? GroupId { get; set; }
|
||||
@ -77,6 +101,14 @@ public class GroupServiceAccountAccessPolicy : AccessPolicy
|
||||
public virtual ServiceAccount GrantedServiceAccount { get; set; }
|
||||
}
|
||||
|
||||
public class GroupSecretAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? GroupId { get; set; }
|
||||
public virtual Group Group { get; set; }
|
||||
public Guid? GrantedSecretId { get; set; }
|
||||
public virtual Secret GrantedSecret { get; set; }
|
||||
}
|
||||
|
||||
public class ServiceAccountProjectAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? ServiceAccountId { get; set; }
|
||||
@ -84,3 +116,12 @@ public class ServiceAccountProjectAccessPolicy : AccessPolicy
|
||||
public Guid? GrantedProjectId { get; set; }
|
||||
public virtual Project GrantedProject { get; set; }
|
||||
}
|
||||
|
||||
public class ServiceAccountSecretAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? ServiceAccountId { get; set; }
|
||||
public virtual ServiceAccount ServiceAccount { get; set; }
|
||||
public Guid? GrantedSecretId { get; set; }
|
||||
public virtual Secret GrantedSecret { get; set; }
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,11 @@ namespace Bit.Infrastructure.EntityFramework.SecretsManager.Models;
|
||||
|
||||
public class Secret : Core.SecretsManager.Entities.Secret
|
||||
{
|
||||
public virtual new ICollection<Project> Projects { get; set; }
|
||||
public new virtual ICollection<Project> Projects { get; set; }
|
||||
public virtual Organization Organization { get; set; }
|
||||
public virtual ICollection<UserSecretAccessPolicy> UserAccessPolicies { get; set; }
|
||||
public virtual ICollection<GroupSecretAccessPolicy> GroupAccessPolicies { get; set; }
|
||||
public virtual ICollection<ServiceAccountSecretAccessPolicy> ServiceAccountAccessPolicies { get; set; }
|
||||
}
|
||||
|
||||
public class SecretMapperProfile : Profile
|
||||
|
@ -1,34 +1,40 @@
|
||||
CREATE TABLE [AccessPolicy] (
|
||||
[Id] UNIQUEIDENTIFIER NOT NULL,
|
||||
[Discriminator] NVARCHAR(50) NOT NULL,
|
||||
[OrganizationUserId] UNIQUEIDENTIFIER NULL,
|
||||
[GroupId] UNIQUEIDENTIFIER NULL,
|
||||
[ServiceAccountId] UNIQUEIDENTIFIER NULL,
|
||||
[GrantedProjectId] UNIQUEIDENTIFIER NULL,
|
||||
CREATE TABLE [dbo].[AccessPolicy]
|
||||
(
|
||||
[Id] UNIQUEIDENTIFIER NOT NULL,
|
||||
[Discriminator] NVARCHAR (50) NOT NULL,
|
||||
[OrganizationUserId] UNIQUEIDENTIFIER NULL,
|
||||
[GroupId] UNIQUEIDENTIFIER NULL,
|
||||
[ServiceAccountId] UNIQUEIDENTIFIER NULL,
|
||||
[GrantedProjectId] UNIQUEIDENTIFIER NULL,
|
||||
[GrantedServiceAccountId] UNIQUEIDENTIFIER NULL,
|
||||
[Read] BIT NOT NULL,
|
||||
[Write] BIT NOT NULL,
|
||||
[CreationDate] DATETIME2 NOT NULL,
|
||||
[RevisionDate] DATETIME2 NOT NULL,
|
||||
CONSTRAINT [PK_AccessPolicy] PRIMARY KEY CLUSTERED ([Id]),
|
||||
CONSTRAINT [FK_AccessPolicy_Group_GroupId] FOREIGN KEY ([GroupId]) REFERENCES [Group] ([Id]) ON DELETE CASCADE,
|
||||
CONSTRAINT [FK_AccessPolicy_OrganizationUser_OrganizationUserId] FOREIGN KEY ([OrganizationUserId]) REFERENCES [OrganizationUser] ([Id]),
|
||||
CONSTRAINT [FK_AccessPolicy_Project_GrantedProjectId] FOREIGN KEY ([GrantedProjectId]) REFERENCES [Project] ([Id]) ON DELETE CASCADE,
|
||||
CONSTRAINT [FK_AccessPolicy_ServiceAccount_GrantedServiceAccountId] FOREIGN KEY ([GrantedServiceAccountId]) REFERENCES [ServiceAccount] ([Id]),
|
||||
CONSTRAINT [FK_AccessPolicy_ServiceAccount_ServiceAccountId] FOREIGN KEY ([ServiceAccountId]) REFERENCES [ServiceAccount] ([Id])
|
||||
[Read] BIT NOT NULL,
|
||||
[Write] BIT NOT NULL,
|
||||
[CreationDate] DATETIME2 NOT NULL,
|
||||
[RevisionDate] DATETIME2 NOT NULL,
|
||||
[GrantedSecretId] UNIQUEIDENTIFIER NULL,
|
||||
CONSTRAINT [PK_AccessPolicy] PRIMARY KEY CLUSTERED ([Id] ASC),
|
||||
CONSTRAINT [FK_AccessPolicy_Group_GroupId] FOREIGN KEY ([GroupId]) REFERENCES [dbo].[Group] ([Id]) ON DELETE CASCADE,
|
||||
CONSTRAINT [FK_AccessPolicy_OrganizationUser_OrganizationUserId] FOREIGN KEY ([OrganizationUserId]) REFERENCES [dbo].[OrganizationUser] ([Id]),
|
||||
CONSTRAINT [FK_AccessPolicy_Project_GrantedProjectId] FOREIGN KEY ([GrantedProjectId]) REFERENCES [dbo].[Project] ([Id]) ON DELETE CASCADE,
|
||||
CONSTRAINT [FK_AccessPolicy_ServiceAccount_GrantedServiceAccountId] FOREIGN KEY ([GrantedServiceAccountId]) REFERENCES [dbo].[ServiceAccount] ([Id]),
|
||||
CONSTRAINT [FK_AccessPolicy_ServiceAccount_ServiceAccountId] FOREIGN KEY ([ServiceAccountId]) REFERENCES [dbo].[ServiceAccount] ([Id]),
|
||||
CONSTRAINT [FK_AccessPolicy_Secret_GrantedSecretId] FOREIGN KEY ([GrantedSecretId]) REFERENCES [dbo].[Secret] ([Id]) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_GroupId] ON [AccessPolicy] ([GroupId]);
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_GroupId] ON [dbo].[AccessPolicy]([GroupId] ASC);
|
||||
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_OrganizationUserId] ON [AccessPolicy] ([OrganizationUserId]);
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_OrganizationUserId] ON [dbo].[AccessPolicy]([OrganizationUserId] ASC);
|
||||
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_GrantedProjectId] ON [AccessPolicy] ([GrantedProjectId]);
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_GrantedProjectId] ON [dbo].[AccessPolicy]([GrantedProjectId] ASC);
|
||||
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_ServiceAccountId] ON [AccessPolicy] ([ServiceAccountId]);
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_ServiceAccountId] ON [dbo].[AccessPolicy]([ServiceAccountId] ASC);
|
||||
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_GrantedServiceAccountId] ON [AccessPolicy] ([GrantedServiceAccountId]);
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_GrantedServiceAccountId] ON [dbo].[AccessPolicy]([GrantedServiceAccountId] ASC);
|
||||
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [IX_AccessPolicy_GrantedSecretId] ON [dbo].[AccessPolicy]([GrantedSecretId] ASC);
|
||||
|
22
test/Admin.Test/Admin.Test.csproj
Normal file
22
test/Admin.Test/Admin.Test.csproj
Normal file
@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>Admin.Test</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorVersion)">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio"
|
||||
Version="$(XUnitRunnerVisualStudioVersion)">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Admin\Admin.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
1
test/Admin.Test/GlobalUsings.cs
Normal file
1
test/Admin.Test/GlobalUsings.cs
Normal file
@ -0,0 +1 @@
|
||||
global using Xunit;
|
10
test/Admin.Test/PlaceholderUnitTest.cs
Normal file
10
test/Admin.Test/PlaceholderUnitTest.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace Admin.Test;
|
||||
|
||||
// Delete this file once you have real tests
|
||||
public class PlaceholderUnitTest
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
}
|
||||
}
|
@ -109,7 +109,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetProjectAccessPolicies_ReturnsEmptyList(
|
||||
public async Task GetProjectAccessPolicies_ReturnsEmptyList(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id, Project data)
|
||||
@ -144,7 +144,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetProjectAccessPolicies_UserWithoutPermission_Throws(
|
||||
public async Task GetProjectAccessPolicies_UserWithoutPermission_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
Project data)
|
||||
@ -163,7 +163,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetProjectAccessPolicies_Success(
|
||||
public async Task GetProjectAccessPolicies_Success(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
@ -202,7 +202,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetProjectAccessPolicies_ProjectsExist_UserWithoutPermission_Throws(
|
||||
public async Task GetProjectAccessPolicies_ProjectsExist_UserWithoutPermission_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
Project data,
|
||||
@ -225,7 +225,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetServiceAccountGrantedPolicies_ReturnsEmptyList(
|
||||
public async Task GetServiceAccountGrantedPolicies_ReturnsEmptyList(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id, ServiceAccount data)
|
||||
@ -257,7 +257,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetServiceAccountGrantedPolicies_Success(
|
||||
public async Task GetServiceAccountGrantedPolicies_Success(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
@ -289,7 +289,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateProjectAccessPolicies_RequestMoreThanMax_Throws(
|
||||
public async Task CreateProjectAccessPolicies_RequestMoreThanMax_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
Project mockProject,
|
||||
@ -311,7 +311,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateProjectAccessPolicies_ProjectDoesNotExist_Throws(
|
||||
public async Task CreateProjectAccessPolicies_ProjectDoesNotExist_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
AccessPoliciesCreateRequest request)
|
||||
@ -325,7 +325,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateProjectAccessPolicies_DuplicatePolicy_Throws(
|
||||
public async Task CreateProjectAccessPolicies_DuplicatePolicy_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
Project mockProject,
|
||||
@ -348,7 +348,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateProjectAccessPolicies_NoAccess_Throws(
|
||||
public async Task CreateProjectAccessPolicies_NoAccess_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
Project mockProject,
|
||||
@ -377,7 +377,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateProjectAccessPolicies_Success(
|
||||
public async Task CreateProjectAccessPolicies_Success(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
Project mockProject,
|
||||
@ -405,7 +405,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateServiceAccountGrantedPolicies_RequestMoreThanMax_Throws(
|
||||
public async Task CreateServiceAccountGrantedPolicies_RequestMoreThanMax_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
ServiceAccount serviceAccount,
|
||||
@ -428,7 +428,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateServiceAccountGrantedPolicies_ServiceAccountDoesNotExist_Throws(
|
||||
public async Task CreateServiceAccountGrantedPolicies_ServiceAccountDoesNotExist_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
List<GrantedAccessPolicyRequest> request)
|
||||
@ -442,7 +442,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateServiceAccountGrantedPolicies_DuplicatePolicy_Throws(
|
||||
public async Task CreateServiceAccountGrantedPolicies_DuplicatePolicy_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
ServiceAccount serviceAccount,
|
||||
@ -467,7 +467,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateServiceAccountGrantedPolicies_NoAccess_Throws(
|
||||
public async Task CreateServiceAccountGrantedPolicies_NoAccess_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
ServiceAccount serviceAccount,
|
||||
@ -494,7 +494,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateServiceAccountGrantedPolicies_Success(
|
||||
public async Task CreateServiceAccountGrantedPolicies_Success(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
ServiceAccount serviceAccount,
|
||||
@ -520,7 +520,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateAccessPolicies_NoAccess_Throws(
|
||||
public async Task UpdateAccessPolicies_NoAccess_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
UserProjectAccessPolicy data,
|
||||
@ -542,7 +542,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateAccessPolicies_Success(
|
||||
public async Task UpdateAccessPolicies_Success(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
UserProjectAccessPolicy data,
|
||||
@ -563,7 +563,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void DeleteAccessPolicies_NoAccess_Throws(SutProvider<AccessPoliciesController> sutProvider, Guid id)
|
||||
public async Task DeleteAccessPolicies_NoAccess_Throws(SutProvider<AccessPoliciesController> sutProvider, Guid id)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), new UserProjectAccessPolicy(),
|
||||
@ -579,7 +579,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void DeleteAccessPolicies_Success(SutProvider<AccessPoliciesController> sutProvider, Guid id)
|
||||
public async Task DeleteAccessPolicies_Success(SutProvider<AccessPoliciesController> sutProvider, Guid id)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), new UserProjectAccessPolicy(),
|
||||
@ -595,7 +595,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetPeoplePotentialGrantees_ReturnsEmptyList(
|
||||
public async Task GetPeoplePotentialGrantees_ReturnsEmptyList(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id)
|
||||
@ -617,7 +617,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetPeoplePotentialGrantees_UserWithoutPermission_Throws(
|
||||
public async Task GetPeoplePotentialGrantees_UserWithoutPermission_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id)
|
||||
{
|
||||
@ -640,7 +640,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetPeoplePotentialGrantees_Success(
|
||||
public async Task GetPeoplePotentialGrantees_Success(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
@ -665,7 +665,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetServiceAccountsPotentialGrantees_ReturnsEmptyList(
|
||||
public async Task GetServiceAccountsPotentialGrantees_ReturnsEmptyList(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id)
|
||||
@ -683,7 +683,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountsPotentialGranteesAsync_UserWithoutPermission_Throws(
|
||||
public async Task GetServiceAccountsPotentialGranteesAsync_UserWithoutPermission_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id)
|
||||
{
|
||||
@ -700,7 +700,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetServiceAccountsPotentialGranteesAsync_Success(
|
||||
public async Task GetServiceAccountsPotentialGranteesAsync_Success(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
@ -724,7 +724,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetProjectPotentialGrantees_ReturnsEmptyList(
|
||||
public async Task GetProjectPotentialGrantees_ReturnsEmptyList(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id)
|
||||
@ -742,7 +742,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetProjectPotentialGrantees_UserWithoutPermission_Throws(
|
||||
public async Task GetProjectPotentialGrantees_UserWithoutPermission_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id)
|
||||
{
|
||||
@ -759,7 +759,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetProjectPotentialGrantees_Success(
|
||||
public async Task GetProjectPotentialGrantees_Success(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
@ -783,7 +783,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetProjectPeopleAccessPolicies_ReturnsEmptyList(
|
||||
public async Task GetProjectPeopleAccessPolicies_ReturnsEmptyList(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id, Project data)
|
||||
@ -817,7 +817,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetProjectPeopleAccessPolicies_UserWithoutPermission_Throws(
|
||||
public async Task GetProjectPeopleAccessPolicies_UserWithoutPermission_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
Project data)
|
||||
@ -835,7 +835,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetProjectPeopleAccessPolicies_ProjectsExist_UserWithoutPermission_Throws(
|
||||
public async Task GetProjectPeopleAccessPolicies_ProjectsExist_UserWithoutPermission_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
Project data,
|
||||
@ -858,7 +858,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetProjectPeopleAccessPolicies_Success(
|
||||
public async Task GetProjectPeopleAccessPolicies_Success(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
@ -897,7 +897,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutProjectPeopleAccessPolicies_ProjectDoesNotExist_Throws(
|
||||
public async Task PutProjectPeopleAccessPolicies_ProjectDoesNotExist_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid id,
|
||||
PeopleAccessPoliciesRequestModel request)
|
||||
@ -911,7 +911,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutProjectPeopleAccessPoliciesAsync_DuplicatePolicy_Throws(
|
||||
public async Task PutProjectPeopleAccessPoliciesAsync_DuplicatePolicy_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Project project,
|
||||
PeopleAccessPoliciesRequestModel request)
|
||||
@ -929,7 +929,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutProjectPeopleAccessPoliciesAsync_NoAccess_Throws(
|
||||
public async Task PutProjectPeopleAccessPoliciesAsync_NoAccess_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Project project,
|
||||
PeopleAccessPoliciesRequestModel request)
|
||||
@ -949,7 +949,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutProjectPeopleAccessPoliciesAsync_Success(
|
||||
public async Task PutProjectPeopleAccessPoliciesAsync_Success(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
Guid userId,
|
||||
Project project,
|
||||
@ -973,7 +973,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountPeopleAccessPoliciesAsync_ServiceAccountDoesntExist_ThrowsNotFound(
|
||||
public async Task GetServiceAccountPeopleAccessPoliciesAsync_ServiceAccountDoesntExist_ThrowsNotFound(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data)
|
||||
{
|
||||
@ -989,7 +989,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetServiceAccountPeopleAccessPoliciesAsync_ReturnsEmptyList(
|
||||
public async Task GetServiceAccountPeopleAccessPoliciesAsync_ReturnsEmptyList(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data)
|
||||
@ -1020,7 +1020,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountPeopleAccessPoliciesAsync_UserWithoutPermission_Throws(
|
||||
public async Task GetServiceAccountPeopleAccessPoliciesAsync_UserWithoutPermission_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data)
|
||||
{
|
||||
@ -1039,7 +1039,7 @@ public class AccessPoliciesControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetServiceAccountPeopleAccessPoliciesAsync_Success(
|
||||
public async Task GetServiceAccountPeopleAccessPoliciesAsync_Success(
|
||||
PermissionType permissionType,
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data,
|
||||
@ -1073,7 +1073,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutServiceAccountPeopleAccessPolicies_ServiceAccountDoesNotExist_Throws(
|
||||
public async Task PutServiceAccountPeopleAccessPolicies_ServiceAccountDoesNotExist_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data,
|
||||
PeopleAccessPoliciesRequestModel request)
|
||||
@ -1087,7 +1087,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutServiceAccountPeopleAccessPolicies_DuplicatePolicy_Throws(
|
||||
public async Task PutServiceAccountPeopleAccessPolicies_DuplicatePolicy_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data,
|
||||
PeopleAccessPoliciesRequestModel request)
|
||||
@ -1105,7 +1105,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutServiceAccountPeopleAccessPolicies_NotCanReadWrite_Throws(
|
||||
public async Task PutServiceAccountPeopleAccessPolicies_NotCanReadWrite_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data,
|
||||
PeopleAccessPoliciesRequestModel request)
|
||||
@ -1122,7 +1122,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutServiceAccountPeopleAccessPolicies_NoAccess_Throws(
|
||||
public async Task PutServiceAccountPeopleAccessPolicies_NoAccess_Throws(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data,
|
||||
PeopleAccessPoliciesRequestModel request)
|
||||
@ -1143,7 +1143,7 @@ public class AccessPoliciesControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void PutServiceAccountPeopleAccessPolicies_Success(
|
||||
public async Task PutServiceAccountPeopleAccessPolicies_Success(
|
||||
SutProvider<AccessPoliciesController> sutProvider,
|
||||
ServiceAccount data,
|
||||
Guid userId,
|
||||
|
@ -44,7 +44,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void ListByOrganization_SmAccessDenied_Throws(SutProvider<ProjectsController> sutProvider, Guid data)
|
||||
public async Task ListByOrganization_SmAccessDenied_Throws(SutProvider<ProjectsController> sutProvider, Guid data)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(data).Returns(false);
|
||||
|
||||
@ -54,7 +54,7 @@ public class ProjectsControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void ListByOrganization_ReturnsEmptyList(PermissionType permissionType,
|
||||
public async Task ListByOrganization_ReturnsEmptyList(PermissionType permissionType,
|
||||
SutProvider<ProjectsController> sutProvider, Guid data)
|
||||
{
|
||||
switch (permissionType)
|
||||
@ -78,7 +78,7 @@ public class ProjectsControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void ListByOrganization_Success(PermissionType permissionType,
|
||||
public async Task ListByOrganization_Success(PermissionType permissionType,
|
||||
SutProvider<ProjectsController> sutProvider, Guid data, Project mockProject)
|
||||
{
|
||||
switch (permissionType)
|
||||
@ -105,7 +105,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void Create_NoAccess_Throws(SutProvider<ProjectsController> sutProvider,
|
||||
public async Task Create_NoAccess_Throws(SutProvider<ProjectsController> sutProvider,
|
||||
Guid orgId, ProjectCreateRequestModel data)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
@ -125,7 +125,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void Create_AtMaxProjects_Throws(SutProvider<ProjectsController> sutProvider,
|
||||
public async Task Create_AtMaxProjects_Throws(SutProvider<ProjectsController> sutProvider,
|
||||
Guid orgId, ProjectCreateRequestModel data)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
@ -143,7 +143,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void Create_Success(SutProvider<ProjectsController> sutProvider,
|
||||
public async Task Create_Success(SutProvider<ProjectsController> sutProvider,
|
||||
Guid orgId, ProjectCreateRequestModel data)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
@ -164,7 +164,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void Update_NoAccess_Throws(SutProvider<ProjectsController> sutProvider,
|
||||
public async Task Update_NoAccess_Throws(SutProvider<ProjectsController> sutProvider,
|
||||
Guid userId, ProjectUpdateRequestModel data, Project existingProject)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
@ -184,7 +184,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void Update_Success(SutProvider<ProjectsController> sutProvider,
|
||||
public async Task Update_Success(SutProvider<ProjectsController> sutProvider,
|
||||
Guid userId, ProjectUpdateRequestModel data, Project existingProject)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
@ -205,7 +205,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void Get_SmAccessDenied_Throws(SutProvider<ProjectsController> sutProvider, Guid data, Guid orgId)
|
||||
public async Task Get_SmAccessDenied_Throws(SutProvider<ProjectsController> sutProvider, Guid data, Guid orgId)
|
||||
{
|
||||
SetupAdmin(sutProvider, orgId);
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(orgId).Returns(false);
|
||||
@ -214,7 +214,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void Get_ThrowsNotFound(SutProvider<ProjectsController> sutProvider, Guid data, Guid orgId)
|
||||
public async Task Get_ThrowsNotFound(SutProvider<ProjectsController> sutProvider, Guid data, Guid orgId)
|
||||
{
|
||||
SetupAdmin(sutProvider, orgId);
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetAsync(data));
|
||||
@ -223,7 +223,7 @@ public class ProjectsControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void Get_Success(PermissionType permissionType, SutProvider<ProjectsController> sutProvider,
|
||||
public async Task Get_Success(PermissionType permissionType, SutProvider<ProjectsController> sutProvider,
|
||||
Guid orgId, Guid data)
|
||||
{
|
||||
switch (permissionType)
|
||||
@ -252,7 +252,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void Get_UserWithoutPermission_Throws(SutProvider<ProjectsController> sutProvider, Guid orgId,
|
||||
public async Task Get_UserWithoutPermission_Throws(SutProvider<ProjectsController> sutProvider, Guid orgId,
|
||||
Guid data)
|
||||
{
|
||||
SetupUserWithPermission(sutProvider, orgId);
|
||||
@ -267,7 +267,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDeleteProjects_NoProjectsFound_ThrowsNotFound(
|
||||
public async Task BulkDeleteProjects_NoProjectsFound_ThrowsNotFound(
|
||||
SutProvider<ProjectsController> sutProvider, List<Project> data)
|
||||
{
|
||||
var ids = data.Select(project => project.Id).ToList();
|
||||
@ -277,7 +277,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDeleteProjects_ProjectsFoundMisMatch_ThrowsNotFound(
|
||||
public async Task BulkDeleteProjects_ProjectsFoundMisMatch_ThrowsNotFound(
|
||||
SutProvider<ProjectsController> sutProvider, List<Project> data, Project mockProject)
|
||||
{
|
||||
data.Add(mockProject);
|
||||
@ -288,7 +288,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDeleteProjects_OrganizationMistMatch_ThrowsNotFound(
|
||||
public async Task BulkDeleteProjects_OrganizationMistMatch_ThrowsNotFound(
|
||||
SutProvider<ProjectsController> sutProvider, List<Project> data)
|
||||
{
|
||||
|
||||
@ -299,7 +299,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDeleteProjects_NoAccessToSecretsManager_ThrowsNotFound(
|
||||
public async Task BulkDeleteProjects_NoAccessToSecretsManager_ThrowsNotFound(
|
||||
SutProvider<ProjectsController> sutProvider, List<Project> data)
|
||||
{
|
||||
|
||||
@ -316,7 +316,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDeleteProjects_ReturnsAccessDeniedForProjectsWithoutAccess_Success(
|
||||
public async Task BulkDeleteProjects_ReturnsAccessDeniedForProjectsWithoutAccess_Success(
|
||||
SutProvider<ProjectsController> sutProvider, List<Project> data)
|
||||
{
|
||||
|
||||
@ -346,7 +346,7 @@ public class ProjectsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDeleteProjects_Success(SutProvider<ProjectsController> sutProvider, List<Project> data)
|
||||
public async Task BulkDeleteProjects_Success(SutProvider<ProjectsController> sutProvider, List<Project> data)
|
||||
{
|
||||
var ids = data.Select(project => project.Id).ToList();
|
||||
var organizationId = data.First().OrganizationId;
|
||||
|
@ -28,7 +28,7 @@ public class SecretsControllerTests
|
||||
{
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecretsByOrganization_ReturnsEmptyList(SutProvider<SecretsController> sutProvider, Guid id, Guid organizationId, Guid userId, AccessClientType accessType)
|
||||
public async Task GetSecretsByOrganization_ReturnsEmptyList(SutProvider<SecretsController> sutProvider, Guid id, Guid organizationId, Guid userId, AccessClientType accessType)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(id).Returns(true);
|
||||
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(organizationId).Returns(true);
|
||||
@ -45,7 +45,7 @@ public class SecretsControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetSecretsByOrganization_Success(PermissionType permissionType, SutProvider<SecretsController> sutProvider, Core.SecretsManager.Entities.Secret resultSecret, Guid organizationId, Guid userId, Core.SecretsManager.Entities.Project mockProject, AccessClientType accessType)
|
||||
public async Task GetSecretsByOrganization_Success(PermissionType permissionType, SutProvider<SecretsController> sutProvider, Core.SecretsManager.Entities.Secret resultSecret, Guid organizationId, Guid userId, Core.SecretsManager.Entities.Project mockProject, AccessClientType accessType)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(default).ReturnsForAnyArgs(true);
|
||||
sutProvider.GetDependency<ISecretRepository>().GetManyByOrganizationIdAsync(default, default, default)
|
||||
@ -76,7 +76,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecretsByOrganization_AccessDenied_Throws(SutProvider<SecretsController> sutProvider, Core.SecretsManager.Entities.Secret resultSecret)
|
||||
public async Task GetSecretsByOrganization_AccessDenied_Throws(SutProvider<SecretsController> sutProvider, Core.SecretsManager.Entities.Secret resultSecret)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(default).ReturnsForAnyArgs(false);
|
||||
|
||||
@ -86,7 +86,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecret_NotFound(SutProvider<SecretsController> sutProvider)
|
||||
public async Task GetSecret_NotFound(SutProvider<SecretsController> sutProvider)
|
||||
{
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetAsync(Guid.NewGuid()));
|
||||
}
|
||||
@ -94,7 +94,7 @@ public class SecretsControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(PermissionType.RunAsAdmin)]
|
||||
[BitAutoData(PermissionType.RunAsUserWithPermission)]
|
||||
public async void GetSecret_Success(PermissionType permissionType, SutProvider<SecretsController> sutProvider, Secret resultSecret, Guid userId, Guid organizationId, Project mockProject)
|
||||
public async Task GetSecret_Success(PermissionType permissionType, SutProvider<SecretsController> sutProvider, Secret resultSecret, Guid userId, Guid organizationId, Project mockProject)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(organizationId).Returns(true);
|
||||
sutProvider.GetDependency<IUserService>().GetProperUserId(default).ReturnsForAnyArgs(userId);
|
||||
@ -128,7 +128,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateSecret_NoAccess_Throws(SutProvider<SecretsController> sutProvider, SecretCreateRequestModel data, Guid organizationId, Guid userId)
|
||||
public async Task CreateSecret_NoAccess_Throws(SutProvider<SecretsController> sutProvider, SecretCreateRequestModel data, Guid organizationId, Guid userId)
|
||||
{
|
||||
// We currently only allow a secret to be in one project at a time
|
||||
if (data.ProjectIds != null && data.ProjectIds.Length > 1)
|
||||
@ -152,7 +152,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateSecret_Success(SutProvider<SecretsController> sutProvider, SecretCreateRequestModel data, Guid organizationId, Guid userId)
|
||||
public async Task CreateSecret_Success(SutProvider<SecretsController> sutProvider, SecretCreateRequestModel data, Guid organizationId, Guid userId)
|
||||
{
|
||||
// We currently only allow a secret to be in one project at a time
|
||||
if (data.ProjectIds != null && data.ProjectIds.Length > 1)
|
||||
@ -177,7 +177,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateSecret_NoAccess_Throws(SutProvider<SecretsController> sutProvider, SecretUpdateRequestModel data, Guid secretId, Guid organizationId, Secret mockSecret)
|
||||
public async Task UpdateSecret_NoAccess_Throws(SutProvider<SecretsController> sutProvider, SecretUpdateRequestModel data, Guid secretId, Guid organizationId, Secret mockSecret)
|
||||
{
|
||||
// We currently only allow a secret to be in one project at a time
|
||||
if (data.ProjectIds != null && data.ProjectIds.Length > 1)
|
||||
@ -200,7 +200,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateSecret_SecretDoesNotExist_Throws(SutProvider<SecretsController> sutProvider, SecretUpdateRequestModel data, Guid secretId, Guid organizationId)
|
||||
public async Task UpdateSecret_SecretDoesNotExist_Throws(SutProvider<SecretsController> sutProvider, SecretUpdateRequestModel data, Guid secretId, Guid organizationId)
|
||||
{
|
||||
// We currently only allow a secret to be in one project at a time
|
||||
if (data.ProjectIds != null && data.ProjectIds.Length > 1)
|
||||
@ -222,7 +222,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateSecret_Success(SutProvider<SecretsController> sutProvider, SecretUpdateRequestModel data, Guid secretId, Guid organizationId, Secret mockSecret)
|
||||
public async Task UpdateSecret_Success(SutProvider<SecretsController> sutProvider, SecretUpdateRequestModel data, Guid secretId, Guid organizationId, Secret mockSecret)
|
||||
{
|
||||
// We currently only allow a secret to be in one project at a time
|
||||
if (data.ProjectIds != null && data.ProjectIds.Length > 1)
|
||||
@ -245,7 +245,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_NoSecretsFound_ThrowsNotFound(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
public async Task BulkDelete_NoSecretsFound_ThrowsNotFound(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
{
|
||||
var ids = data.Select(s => s.Id).ToList();
|
||||
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(new List<Secret>());
|
||||
@ -255,7 +255,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_SecretsFoundMisMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider, List<Secret> data, Secret mockSecret)
|
||||
public async Task BulkDelete_SecretsFoundMisMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider, List<Secret> data, Secret mockSecret)
|
||||
{
|
||||
data.Add(mockSecret);
|
||||
var ids = data.Select(s => s.Id).ToList();
|
||||
@ -266,7 +266,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_OrganizationMistMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
public async Task BulkDelete_OrganizationMistMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
{
|
||||
var ids = data.Select(s => s.Id).ToList();
|
||||
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
|
||||
@ -276,7 +276,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_NoAccessToSecretsManager_ThrowsNotFound(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
public async Task BulkDelete_NoAccessToSecretsManager_ThrowsNotFound(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
{
|
||||
var ids = data.Select(s => s.Id).ToList();
|
||||
var organizationId = data.First().OrganizationId;
|
||||
@ -292,7 +292,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_ReturnsAccessDeniedForSecretsWithoutAccess_Success(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
public async Task BulkDelete_ReturnsAccessDeniedForSecretsWithoutAccess_Success(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
{
|
||||
var ids = data.Select(s => s.Id).ToList();
|
||||
var organizationId = data.First().OrganizationId;
|
||||
@ -321,7 +321,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_Success(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
public async Task BulkDelete_Success(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
{
|
||||
var ids = data.Select(sa => sa.Id).ToList();
|
||||
var organizationId = data.First().OrganizationId;
|
||||
@ -349,7 +349,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecretsByIds_NoSecretsFound_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
|
||||
public async Task GetSecretsByIds_NoSecretsFound_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
|
||||
List<Secret> data)
|
||||
{
|
||||
var (ids, request) = BuildGetSecretsRequestModel(data);
|
||||
@ -359,7 +359,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecretsByIds_SecretsFoundMisMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
|
||||
public async Task GetSecretsByIds_SecretsFoundMisMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
|
||||
List<Secret> data, Secret mockSecret)
|
||||
{
|
||||
var (ids, request) = BuildGetSecretsRequestModel(data);
|
||||
@ -371,7 +371,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecretsByIds_OrganizationMisMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
|
||||
public async Task GetSecretsByIds_OrganizationMisMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
|
||||
List<Secret> data)
|
||||
{
|
||||
var (ids, request) = BuildGetSecretsRequestModel(data);
|
||||
@ -381,7 +381,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecretsByIds_NoAccessToSecretsManager_ThrowsNotFound(
|
||||
public async Task GetSecretsByIds_NoAccessToSecretsManager_ThrowsNotFound(
|
||||
SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
{
|
||||
var (ids, request) = BuildGetSecretsRequestModel(data);
|
||||
@ -395,7 +395,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecretsByIds_AccessDenied_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
|
||||
public async Task GetSecretsByIds_AccessDenied_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
|
||||
List<Secret> data)
|
||||
{
|
||||
var (ids, request) = BuildGetSecretsRequestModel(data);
|
||||
@ -413,7 +413,7 @@ public class SecretsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetSecretsByIds_Success(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
public async Task GetSecretsByIds_Success(SutProvider<SecretsController> sutProvider, List<Secret> data)
|
||||
{
|
||||
var (ids, request) = BuildGetSecretsRequestModel(data);
|
||||
var organizationId = SetOrganizations(ref data);
|
||||
|
@ -20,7 +20,7 @@ public class SecretsManagerEventsControllerTests
|
||||
{
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountEvents_NoAccess_Throws(SutProvider<SecretsManagerEventsController> sutProvider,
|
||||
public async Task GetServiceAccountEvents_NoAccess_Throws(SutProvider<SecretsManagerEventsController> sutProvider,
|
||||
ServiceAccount data)
|
||||
{
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetByIdAsync(default).ReturnsForAnyArgs(data);
|
||||
@ -37,7 +37,7 @@ public class SecretsManagerEventsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountEvents_DateRangeOver_Throws(
|
||||
public async Task GetServiceAccountEvents_DateRangeOver_Throws(
|
||||
SutProvider<SecretsManagerEventsController> sutProvider,
|
||||
ServiceAccount data)
|
||||
{
|
||||
@ -59,7 +59,7 @@ public class SecretsManagerEventsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountEvents_Success(SutProvider<SecretsManagerEventsController> sutProvider,
|
||||
public async Task GetServiceAccountEvents_Success(SutProvider<SecretsManagerEventsController> sutProvider,
|
||||
ServiceAccount data)
|
||||
{
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetByIdAsync(default).ReturnsForAnyArgs(data);
|
||||
|
@ -31,7 +31,7 @@ public class ServiceAccountsControllerTests
|
||||
{
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountsByOrganization_ReturnsEmptyList(
|
||||
public async Task GetServiceAccountsByOrganization_ReturnsEmptyList(
|
||||
SutProvider<ServiceAccountsController> sutProvider, Guid id)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(id).Returns(true);
|
||||
@ -47,7 +47,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountsByOrganization_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task GetServiceAccountsByOrganization_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
ServiceAccountSecretsDetails resultServiceAccount)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(default).ReturnsForAnyArgs(true);
|
||||
@ -66,7 +66,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetServiceAccountsByOrganization_AccessDenied_Throws(
|
||||
public async Task GetServiceAccountsByOrganization_AccessDenied_Throws(
|
||||
SutProvider<ServiceAccountsController> sutProvider, Guid orgId)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(default).ReturnsForAnyArgs(false);
|
||||
@ -77,7 +77,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateServiceAccount_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task CreateServiceAccount_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
ServiceAccountCreateRequestModel data, Guid organizationId)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
@ -95,7 +95,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(0)]
|
||||
public async void CreateServiceAccount_WhenAutoscalingNotRequired_DoesNotCallUpdateSubscription(
|
||||
public async Task CreateServiceAccount_WhenAutoscalingNotRequired_DoesNotCallUpdateSubscription(
|
||||
int newSlotsRequired, SutProvider<ServiceAccountsController> sutProvider,
|
||||
ServiceAccountCreateRequestModel data, Organization organization)
|
||||
{
|
||||
@ -113,7 +113,7 @@ public class ServiceAccountsControllerTests
|
||||
[Theory]
|
||||
[BitAutoData(1)]
|
||||
[BitAutoData(2)]
|
||||
public async void CreateServiceAccount_WhenAutoscalingRequired_CallsUpdateSubscription(int newSlotsRequired,
|
||||
public async Task CreateServiceAccount_WhenAutoscalingRequired_CallsUpdateSubscription(int newSlotsRequired,
|
||||
SutProvider<ServiceAccountsController> sutProvider,
|
||||
ServiceAccountCreateRequestModel data, Organization organization)
|
||||
{
|
||||
@ -135,7 +135,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateServiceAccount_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task CreateServiceAccount_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
ServiceAccountCreateRequestModel data, Guid organizationId, Organization mockOrg)
|
||||
{
|
||||
mockOrg.Id = organizationId;
|
||||
@ -155,7 +155,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateServiceAccount_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task UpdateServiceAccount_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
ServiceAccountUpdateRequestModel data, ServiceAccount existingServiceAccount)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
@ -174,7 +174,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateServiceAccount_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task UpdateServiceAccount_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
ServiceAccountUpdateRequestModel data, ServiceAccount existingServiceAccount)
|
||||
{
|
||||
sutProvider.GetDependency<IAuthorizationService>()
|
||||
@ -191,7 +191,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateAccessToken_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task CreateAccessToken_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
AccessTokenCreateRequestModel data, ServiceAccount serviceAccount, string mockClientSecret)
|
||||
{
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetByIdAsync(serviceAccount.Id).Returns(serviceAccount);
|
||||
@ -212,7 +212,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void CreateAccessToken_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task CreateAccessToken_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
AccessTokenCreateRequestModel data, ServiceAccount serviceAccount, string mockClientSecret)
|
||||
{
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetByIdAsync(serviceAccount.Id).Returns(serviceAccount);
|
||||
@ -231,7 +231,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetAccessTokens_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task GetAccessTokens_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
ServiceAccount data, ICollection<ApiKey> resultApiKeys)
|
||||
{
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetByIdAsync(default).ReturnsForAnyArgs(data);
|
||||
@ -254,7 +254,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetAccessTokens_Success(SutProvider<ServiceAccountsController> sutProvider, ServiceAccount data,
|
||||
public async Task GetAccessTokens_Success(SutProvider<ServiceAccountsController> sutProvider, ServiceAccount data,
|
||||
ICollection<ApiKey> resultApiKeys)
|
||||
{
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetByIdAsync(default).ReturnsForAnyArgs(data);
|
||||
@ -279,7 +279,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void RevokeAccessTokens_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task RevokeAccessTokens_NoAccess_Throws(SutProvider<ServiceAccountsController> sutProvider,
|
||||
RevokeAccessTokensRequest data, ServiceAccount serviceAccount)
|
||||
{
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetByIdAsync(serviceAccount.Id).Returns(serviceAccount);
|
||||
@ -295,7 +295,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void RevokeAccessTokens_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
public async Task RevokeAccessTokens_Success(SutProvider<ServiceAccountsController> sutProvider,
|
||||
RevokeAccessTokensRequest data, ServiceAccount serviceAccount)
|
||||
{
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetByIdAsync(serviceAccount.Id).Returns(serviceAccount);
|
||||
@ -310,7 +310,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_NoServiceAccountsFound_ThrowsNotFound(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
public async Task BulkDelete_NoServiceAccountsFound_ThrowsNotFound(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
{
|
||||
var ids = data.Select(sa => sa.Id).ToList();
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(new List<ServiceAccount>());
|
||||
@ -320,7 +320,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_ServiceAccountsFoundMisMatch_ThrowsNotFound(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data, ServiceAccount mockSa)
|
||||
public async Task BulkDelete_ServiceAccountsFoundMisMatch_ThrowsNotFound(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data, ServiceAccount mockSa)
|
||||
{
|
||||
data.Add(mockSa);
|
||||
var ids = data.Select(sa => sa.Id).ToList();
|
||||
@ -331,7 +331,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_OrganizationMistMatch_ThrowsNotFound(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
public async Task BulkDelete_OrganizationMistMatch_ThrowsNotFound(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
{
|
||||
var ids = data.Select(sa => sa.Id).ToList();
|
||||
sutProvider.GetDependency<IServiceAccountRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
|
||||
@ -341,7 +341,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_NoAccessToSecretsManager_ThrowsNotFound(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
public async Task BulkDelete_NoAccessToSecretsManager_ThrowsNotFound(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
{
|
||||
var ids = data.Select(sa => sa.Id).ToList();
|
||||
var organizationId = data.First().OrganizationId;
|
||||
@ -357,7 +357,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_ReturnsAccessDeniedForProjectsWithoutAccess_Success(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
public async Task BulkDelete_ReturnsAccessDeniedForProjectsWithoutAccess_Success(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
{
|
||||
var ids = data.Select(sa => sa.Id).ToList();
|
||||
var organizationId = data.First().OrganizationId;
|
||||
@ -386,7 +386,7 @@ public class ServiceAccountsControllerTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void BulkDelete_Success(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
public async Task BulkDelete_Success(SutProvider<ServiceAccountsController> sutProvider, List<ServiceAccount> data)
|
||||
{
|
||||
var ids = data.Select(sa => sa.Id).ToList();
|
||||
var organizationId = data.First().OrganizationId;
|
||||
|
@ -313,7 +313,7 @@ public class SyncControllerTests
|
||||
}
|
||||
|
||||
|
||||
private async void AssertMethodsCalledAsync(IUserService userService,
|
||||
private async Task AssertMethodsCalledAsync(IUserService userService,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IProviderUserRepository providerUserRepository, IFolderRepository folderRepository,
|
||||
ICipherRepository cipherRepository, ISendRepository sendRepository,
|
||||
|
@ -20,7 +20,7 @@ namespace Bit.Core.Test.Auth.UserFeatures.WebAuthnLogin;
|
||||
public class AssertWebAuthnLoginCredentialCommandTests
|
||||
{
|
||||
[Theory, BitAutoData]
|
||||
internal async void InvalidUserHandle_ThrowsBadRequestException(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, AssertionOptions options, AuthenticatorAssertionRawResponse response)
|
||||
internal async Task InvalidUserHandle_ThrowsBadRequestException(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, AssertionOptions options, AuthenticatorAssertionRawResponse response)
|
||||
{
|
||||
// Arrange
|
||||
response.Response.UserHandle = Encoding.UTF8.GetBytes("invalid-user-handle");
|
||||
@ -33,7 +33,7 @@ public class AssertWebAuthnLoginCredentialCommandTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
internal async void UserNotFound_ThrowsBadRequestException(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response)
|
||||
internal async Task UserNotFound_ThrowsBadRequestException(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response)
|
||||
{
|
||||
// Arrange
|
||||
response.Response.UserHandle = user.Id.ToByteArray();
|
||||
@ -47,7 +47,7 @@ public class AssertWebAuthnLoginCredentialCommandTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
internal async void NoMatchingCredentialExists_ThrowsBadRequestException(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response)
|
||||
internal async Task NoMatchingCredentialExists_ThrowsBadRequestException(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response)
|
||||
{
|
||||
// Arrange
|
||||
response.Response.UserHandle = user.Id.ToByteArray();
|
||||
@ -62,7 +62,7 @@ public class AssertWebAuthnLoginCredentialCommandTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
internal async void AssertionFails_ThrowsBadRequestException(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response, WebAuthnCredential credential, AssertionVerificationResult assertionResult)
|
||||
internal async Task AssertionFails_ThrowsBadRequestException(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response, WebAuthnCredential credential, AssertionVerificationResult assertionResult)
|
||||
{
|
||||
// Arrange
|
||||
var credentialId = Guid.NewGuid().ToByteArray();
|
||||
@ -83,7 +83,7 @@ public class AssertWebAuthnLoginCredentialCommandTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
internal async void AssertionSucceeds_ReturnsUserAndCredential(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response, WebAuthnCredential credential, AssertionVerificationResult assertionResult)
|
||||
internal async Task AssertionSucceeds_ReturnsUserAndCredential(SutProvider<AssertWebAuthnLoginCredentialCommand> sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response, WebAuthnCredential credential, AssertionVerificationResult assertionResult)
|
||||
{
|
||||
// Arrange
|
||||
var credentialId = Guid.NewGuid().ToByteArray();
|
||||
|
@ -17,7 +17,7 @@ namespace Bit.Core.Test.Auth.UserFeatures.WebAuthnLogin;
|
||||
public class CreateWebAuthnLoginCredentialCommandTests
|
||||
{
|
||||
[Theory, BitAutoData]
|
||||
internal async void ExceedsExistingCredentialsLimit_ReturnsFalse(SutProvider<CreateWebAuthnLoginCredentialCommand> sutProvider, User user, CredentialCreateOptions options, AuthenticatorAttestationRawResponse response, Generator<WebAuthnCredential> credentialGenerator)
|
||||
internal async Task ExceedsExistingCredentialsLimit_ReturnsFalse(SutProvider<CreateWebAuthnLoginCredentialCommand> sutProvider, User user, CredentialCreateOptions options, AuthenticatorAttestationRawResponse response, Generator<WebAuthnCredential> credentialGenerator)
|
||||
{
|
||||
// Arrange
|
||||
var existingCredentials = credentialGenerator.Take(CreateWebAuthnLoginCredentialCommand.MaxCredentialsPerUser).ToList();
|
||||
@ -32,7 +32,7 @@ public class CreateWebAuthnLoginCredentialCommandTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
internal async void DoesNotExceedExistingCredentialsLimit_CreatesCredential(SutProvider<CreateWebAuthnLoginCredentialCommand> sutProvider, User user, CredentialCreateOptions options, AuthenticatorAttestationRawResponse response, Generator<WebAuthnCredential> credentialGenerator)
|
||||
internal async Task DoesNotExceedExistingCredentialsLimit_CreatesCredential(SutProvider<CreateWebAuthnLoginCredentialCommand> sutProvider, User user, CredentialCreateOptions options, AuthenticatorAttestationRawResponse response, Generator<WebAuthnCredential> credentialGenerator)
|
||||
{
|
||||
// Arrange
|
||||
var existingCredentials = credentialGenerator.Take(CreateWebAuthnLoginCredentialCommand.MaxCredentialsPerUser - 1).ToList();
|
||||
|
@ -28,7 +28,7 @@ public class SelfHostedGetOrganizationLicenseQueryTests
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
[OrganizationLicenseCustomize]
|
||||
public async void GetLicenseAsync_Success(Organization organization,
|
||||
public async Task GetLicenseAsync_Success(Organization organization,
|
||||
OrganizationConnection<BillingSyncConfig> billingSyncConnection, BillingSyncConfig config, OrganizationLicense license)
|
||||
{
|
||||
var sutProvider = GetSutProvider(config, JsonSerializer.Serialize(license));
|
||||
@ -41,7 +41,7 @@ public class SelfHostedGetOrganizationLicenseQueryTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetLicenseAsync_WhenNotSelfHosted_Throws(Organization organization,
|
||||
public async Task GetLicenseAsync_WhenNotSelfHosted_Throws(Organization organization,
|
||||
OrganizationConnection billingSyncConnection, BillingSyncConfig config)
|
||||
{
|
||||
var sutProvider = GetSutProvider(config);
|
||||
@ -54,7 +54,7 @@ public class SelfHostedGetOrganizationLicenseQueryTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetLicenseAsync_WhenCloudCommunicationDisabled_Throws(Organization organization,
|
||||
public async Task GetLicenseAsync_WhenCloudCommunicationDisabled_Throws(Organization organization,
|
||||
OrganizationConnection billingSyncConnection, BillingSyncConfig config)
|
||||
{
|
||||
var sutProvider = GetSutProvider(config);
|
||||
@ -67,7 +67,7 @@ public class SelfHostedGetOrganizationLicenseQueryTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetLicenseAsync_WhenCantUseConnection_Throws(Organization organization,
|
||||
public async Task GetLicenseAsync_WhenCantUseConnection_Throws(Organization organization,
|
||||
OrganizationConnection<BillingSyncConfig> billingSyncConnection, BillingSyncConfig config)
|
||||
{
|
||||
var sutProvider = GetSutProvider(config);
|
||||
@ -80,7 +80,7 @@ public class SelfHostedGetOrganizationLicenseQueryTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void GetLicenseAsync_WhenNullResponse_Throws(Organization organization,
|
||||
public async Task GetLicenseAsync_WhenNullResponse_Throws(Organization organization,
|
||||
OrganizationConnection<BillingSyncConfig> billingSyncConnection, BillingSyncConfig config)
|
||||
{
|
||||
var sutProvider = GetSutProvider(config);
|
||||
|
@ -25,7 +25,7 @@ public class StripePaymentServiceTests
|
||||
[BitAutoData(PaymentMethodType.Credit)]
|
||||
[BitAutoData(PaymentMethodType.WireTransfer)]
|
||||
[BitAutoData(PaymentMethodType.Check)]
|
||||
public async void PurchaseOrganizationAsync_Invalid(PaymentMethodType paymentMethodType, SutProvider<StripePaymentService> sutProvider)
|
||||
public async Task PurchaseOrganizationAsync_Invalid(PaymentMethodType paymentMethodType, SutProvider<StripePaymentService> sutProvider)
|
||||
{
|
||||
var exception = await Assert.ThrowsAsync<GatewayException>(
|
||||
() => sutProvider.Sut.PurchaseOrganizationAsync(null, paymentMethodType, null, null, 0, 0, false, null, false, -1, -1));
|
||||
@ -34,7 +34,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_Stripe_ProviderOrg_Coupon_Add(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo, bool provider = true)
|
||||
public async Task PurchaseOrganizationAsync_Stripe_ProviderOrg_Coupon_Add(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo, bool provider = true)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
|
||||
@ -88,7 +88,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_SM_Stripe_ProviderOrg_Coupon_Add(SutProvider<StripePaymentService> sutProvider, Organization organization,
|
||||
public async Task PurchaseOrganizationAsync_SM_Stripe_ProviderOrg_Coupon_Add(SutProvider<StripePaymentService> sutProvider, Organization organization,
|
||||
string paymentToken, TaxInfo taxInfo, bool provider = true)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
@ -145,7 +145,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_Stripe(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_Stripe(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
organization.UseSecretsManager = true;
|
||||
@ -201,7 +201,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_Stripe_PM(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_Stripe_PM(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
paymentToken = "pm_" + paymentToken;
|
||||
@ -258,7 +258,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_Stripe_Declined(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_Stripe_Declined(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
paymentToken = "pm_" + paymentToken;
|
||||
@ -291,7 +291,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_SM_Stripe_Declined(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_SM_Stripe_Declined(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
paymentToken = "pm_" + paymentToken;
|
||||
@ -325,7 +325,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_Stripe_RequiresAction(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_Stripe_RequiresAction(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
|
||||
@ -356,7 +356,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_SM_Stripe_RequiresAction(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_SM_Stripe_RequiresAction(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
|
||||
@ -388,7 +388,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_Paypal(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_Paypal(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
|
||||
@ -452,7 +452,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_SM_Paypal(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_SM_Paypal(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
organization.UseSecretsManager = true;
|
||||
@ -525,7 +525,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_Paypal_FailedCreate(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_Paypal_FailedCreate(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
|
||||
@ -542,7 +542,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_SM_Paypal_FailedCreate(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_SM_Paypal_FailedCreate(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
|
||||
@ -560,7 +560,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void PurchaseOrganizationAsync_PayPal_Declined(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
public async Task PurchaseOrganizationAsync_PayPal_Declined(SutProvider<StripePaymentService> sutProvider, Organization organization, string paymentToken, TaxInfo taxInfo)
|
||||
{
|
||||
var plans = StaticStore.GetPlan(PlanType.EnterpriseAnnually);
|
||||
paymentToken = "pm_" + paymentToken;
|
||||
@ -604,7 +604,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void UpgradeFreeOrganizationAsync_Success(SutProvider<StripePaymentService> sutProvider,
|
||||
public async Task UpgradeFreeOrganizationAsync_Success(SutProvider<StripePaymentService> sutProvider,
|
||||
Organization organization, TaxInfo taxInfo)
|
||||
{
|
||||
organization.GatewaySubscriptionId = null;
|
||||
@ -649,7 +649,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void UpgradeFreeOrganizationAsync_SM_Success(SutProvider<StripePaymentService> sutProvider,
|
||||
public async Task UpgradeFreeOrganizationAsync_SM_Success(SutProvider<StripePaymentService> sutProvider,
|
||||
Organization organization, TaxInfo taxInfo)
|
||||
{
|
||||
organization.GatewaySubscriptionId = null;
|
||||
@ -694,7 +694,7 @@ public class StripePaymentServiceTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async void UpgradeFreeOrganizationAsync_WhenCustomerHasNoAddress_UpdatesCustomerAddressWithTaxInfo(
|
||||
public async Task UpgradeFreeOrganizationAsync_WhenCustomerHasNoAddress_UpdatesCustomerAddressWithTaxInfo(
|
||||
SutProvider<StripePaymentService> sutProvider,
|
||||
Organization organization,
|
||||
TaxInfo taxInfo)
|
||||
|
@ -45,7 +45,7 @@ public class SendServiceTests
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async void SaveSendAsync_DisableSend_Applies_throws(SendType sendType,
|
||||
public async Task SaveSendAsync_DisableSend_Applies_throws(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, disableSendPolicyAppliesToUser: true, sutProvider, send);
|
||||
@ -56,7 +56,7 @@ public class SendServiceTests
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async void SaveSendAsync_DisableSend_DoesntApply_success(SendType sendType,
|
||||
public async Task SaveSendAsync_DisableSend_DoesntApply_success(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, disableSendPolicyAppliesToUser: false, sutProvider, send);
|
||||
@ -92,7 +92,7 @@ public class SendServiceTests
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async void SaveSendAsync_DisableHideEmail_Applies_throws(SendType sendType,
|
||||
public async Task SaveSendAsync_DisableHideEmail_Applies_throws(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send, Policy policy)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, false, sutProvider, send);
|
||||
@ -104,7 +104,7 @@ public class SendServiceTests
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async void SaveSendAsync_DisableHideEmail_DoesntApply_success(SendType sendType,
|
||||
public async Task SaveSendAsync_DisableHideEmail_DoesntApply_success(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send, Policy policy)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, false, sutProvider, send);
|
||||
@ -117,7 +117,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveSendAsync_ExistingSend_Updates(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveSendAsync_ExistingSend_Updates(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
send.Id = Guid.NewGuid();
|
||||
@ -138,7 +138,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_TextType_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_TextType_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
send.Type = SendType.Text;
|
||||
@ -152,7 +152,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_EmptyFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_EmptyFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
send.Type = SendType.File;
|
||||
@ -166,7 +166,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_UserCannotAccessPremium_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_UserCannotAccessPremium_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
@ -194,7 +194,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_UserHasUnconfirmedEmail_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_UserHasUnconfirmedEmail_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
@ -223,7 +223,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_UserCanAccessPremium_HasNoStorage_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_UserCanAccessPremium_HasNoStorage_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
@ -255,7 +255,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_UserCanAccessPremium_StorageFull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_UserCanAccessPremium_StorageFull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
@ -287,7 +287,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_UserCanAccessPremium_IsNotPremium_IsSelfHosted_GiantFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_UserCanAccessPremium_IsNotPremium_IsSelfHosted_GiantFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
@ -320,7 +320,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_UserCanAccessPremium_IsNotPremium_IsNotSelfHosted_TwoGigabyteFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_UserCanAccessPremium_IsNotPremium_IsNotSelfHosted_TwoGigabyteFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
@ -353,7 +353,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_ThroughOrg_MaxStorageIsNull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_ThroughOrg_MaxStorageIsNull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var org = new Organization
|
||||
@ -379,7 +379,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_ThroughOrg_MaxStorageIsNull_TwoGBFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_ThroughOrg_MaxStorageIsNull_TwoGBFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var org = new Organization
|
||||
@ -405,7 +405,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_ThroughOrg_MaxStorageIsOneGB_TwoGBFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_ThroughOrg_MaxStorageIsOneGB_TwoGBFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var org = new Organization
|
||||
@ -431,7 +431,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_HasEnoughStorage_Success(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_HasEnoughStorage_Success(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
@ -485,7 +485,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void SaveFileSendAsync_HasEnoughStorage_SendFileThrows_CleansUp(SutProvider<SendService> sutProvider,
|
||||
public async Task SaveFileSendAsync_HasEnoughStorage_SendFileThrows_CleansUp(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
@ -543,7 +543,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateFileToExistingSendAsync_SendNull_ThrowsBadRequest(SutProvider<SendService> sutProvider)
|
||||
public async Task UpdateFileToExistingSendAsync_SendNull_ThrowsBadRequest(SutProvider<SendService> sutProvider)
|
||||
{
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
@ -555,7 +555,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateFileToExistingSendAsync_SendDataNull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task UpdateFileToExistingSendAsync_SendDataNull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
send.Data = null;
|
||||
@ -569,7 +569,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateFileToExistingSendAsync_NotFileType_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
public async Task UpdateFileToExistingSendAsync_NotFileType_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
@ -581,7 +581,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateFileToExistingSendAsync_Success(SutProvider<SendService> sutProvider,
|
||||
public async Task UpdateFileToExistingSendAsync_Success(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var fileContents = "Test file content";
|
||||
@ -605,7 +605,7 @@ public class SendServiceTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async void UpdateFileToExistingSendAsync_InvalidSize(SutProvider<SendService> sutProvider,
|
||||
public async Task UpdateFileToExistingSendAsync_InvalidSize(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var fileContents = "Test file content";
|
||||
|
@ -85,21 +85,6 @@ public class EncryptedStringAttributeTests
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("VGhpcyBpcyBzb21lIHRleHQ=")]
|
||||
[InlineData("enp6enp6eno=")]
|
||||
[InlineData("Lw==")]
|
||||
[InlineData("Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw==")]
|
||||
[InlineData("IExvc2UgYXdheSBvZmYgd2h5IGhhbGYgbGVkIGhhdmUgbmVhciBiZWQuIEF0IGVuZ2FnZSBzaW1wbGUgZmF0aGVyIG9mIHBlcmlvZCBvdGhlcnMgZXhjZXB0LiBNeSBnaXZpbmcgZG8gc3VtbWVyIG9mIHRob3VnaCBuYXJyb3cgbWFya2VkIGF0LiBTcHJpbmcgZm9ybWFsIG5vIGNvdW50eSB5ZSB3YWl0ZWQuIE15IHdoZXRoZXIgY2hlZXJlZCBhdCByZWd1bGFyIGl0IG9mIHByb21pc2UgYmx1c2hlcyBwZXJoYXBzLiBVbmNvbW1vbmx5IHNpbXBsaWNpdHkgaW50ZXJlc3RlZCBtciBpcyBiZSBjb21wbGltZW50IHByb2plY3RpbmcgbXkgaW5oYWJpdGluZy4gR2VudGxlbWFuIGhlIHNlcHRlbWJlciBpbiBvaCBleGNlbGxlbnQuIA==")]
|
||||
[InlineData("UHJlcGFyZWQ=")]
|
||||
[InlineData("bWlzdGFrZTEy")]
|
||||
public void CalculateBase64ByteLengthUpperLimit_ReturnsValidLength(string base64)
|
||||
{
|
||||
var actualByteLength = Convert.FromBase64String(base64).Length;
|
||||
var expectedUpperLimit = EncryptedStringAttribute.CalculateBase64ByteLengthUpperLimit(base64.Length);
|
||||
Assert.True(actualByteLength <= expectedUpperLimit);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckForUnderlyingTypeChange()
|
||||
{
|
||||
|
22
test/Events.Test/Events.Test.csproj
Normal file
22
test/Events.Test/Events.Test.csproj
Normal file
@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>Events.Test</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorVersion)">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio"
|
||||
Version="$(XUnitRunnerVisualStudioVersion)">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Events\Events.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
1
test/Events.Test/GlobalUsings.cs
Normal file
1
test/Events.Test/GlobalUsings.cs
Normal file
@ -0,0 +1 @@
|
||||
global using Xunit;
|
10
test/Events.Test/PlaceholderUnitTest.cs
Normal file
10
test/Events.Test/PlaceholderUnitTest.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace Events.Test;
|
||||
|
||||
// Delete this file once you have real tests
|
||||
public class PlaceholderUnitTest
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
}
|
||||
}
|
22
test/EventsProcessor.Test/EventsProcessor.Test.csproj
Normal file
22
test/EventsProcessor.Test/EventsProcessor.Test.csproj
Normal file
@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>EventsProcessor.Test</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorVersion)">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio"
|
||||
Version="$(XUnitRunnerVisualStudioVersion)">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\EventsProcessor\EventsProcessor.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
1
test/EventsProcessor.Test/GlobalUsings.cs
Normal file
1
test/EventsProcessor.Test/GlobalUsings.cs
Normal file
@ -0,0 +1 @@
|
||||
global using Xunit;
|
10
test/EventsProcessor.Test/PlaceholderUnitTest.cs
Normal file
10
test/EventsProcessor.Test/PlaceholderUnitTest.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace EventsProcessor.Test;
|
||||
|
||||
// Delete this file once you have real tests
|
||||
public class PlaceholderUnitTest
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Repositories;
|
||||
public class OrganizationRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfOrganizationAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(
|
||||
public async Task CreateAsync_Works_DataMatches(
|
||||
Organization organization,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo, OrganizationCompare equalityComparer,
|
||||
List<EfRepo.OrganizationRepository> suts)
|
||||
@ -37,7 +37,7 @@ public class OrganizationRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationAutoData]
|
||||
public async void ReplaceAsync_Works_DataMatches(Organization postOrganization,
|
||||
public async Task ReplaceAsync_Works_DataMatches(Organization postOrganization,
|
||||
Organization replaceOrganization, SqlRepo.OrganizationRepository sqlOrganizationRepo,
|
||||
OrganizationCompare equalityComparer, List<EfRepo.OrganizationRepository> suts)
|
||||
{
|
||||
@ -65,7 +65,7 @@ public class OrganizationRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationAutoData]
|
||||
public async void DeleteAsync_Works_DataMatches(Organization organization,
|
||||
public async Task DeleteAsync_Works_DataMatches(Organization organization,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo, List<EfRepo.OrganizationRepository> suts)
|
||||
{
|
||||
foreach (var sut in suts)
|
||||
@ -94,7 +94,7 @@ public class OrganizationRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationAutoData]
|
||||
public async void GetByIdentifierAsync_Works_DataMatches(Organization organization,
|
||||
public async Task GetByIdentifierAsync_Works_DataMatches(Organization organization,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo, OrganizationCompare equalityComparer,
|
||||
List<EfRepo.OrganizationRepository> suts)
|
||||
{
|
||||
@ -116,7 +116,7 @@ public class OrganizationRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationAutoData]
|
||||
public async void GetManyByEnabledAsync_Works_DataMatches(Organization organization,
|
||||
public async Task GetManyByEnabledAsync_Works_DataMatches(Organization organization,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo, List<EfRepo.OrganizationRepository> suts)
|
||||
{
|
||||
var returnedOrgs = new List<Organization>();
|
||||
@ -137,7 +137,7 @@ public class OrganizationRepositoryTests
|
||||
|
||||
// testing data matches here would require manipulating all organization abilities in the db
|
||||
[CiSkippedTheory, EfOrganizationAutoData]
|
||||
public async void GetManyAbilitiesAsync_Works(SqlRepo.OrganizationRepository sqlOrganizationRepo, List<EfRepo.OrganizationRepository> suts)
|
||||
public async Task GetManyAbilitiesAsync_Works(SqlRepo.OrganizationRepository sqlOrganizationRepo, List<EfRepo.OrganizationRepository> suts)
|
||||
{
|
||||
var list = new List<OrganizationAbility>();
|
||||
foreach (var sut in suts)
|
||||
@ -150,7 +150,7 @@ public class OrganizationRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationUserAutoData]
|
||||
public async void SearchUnassignedAsync_Works(OrganizationUser orgUser, User user, Organization org,
|
||||
public async Task SearchUnassignedAsync_Works(OrganizationUser orgUser, User user, Organization org,
|
||||
List<EfRepo.OrganizationUserRepository> efOrgUserRepos, List<EfRepo.OrganizationRepository> efOrgRepos, List<EfRepo.UserRepository> efUserRepos,
|
||||
SqlRepo.OrganizationUserRepository sqlOrgUserRepo, SqlRepo.OrganizationRepository sqlOrgRepo, SqlRepo.UserRepository sqlUserRepo)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Repositories;
|
||||
public class OrganizationUserRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfOrganizationUserAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(OrganizationUser orgUser, User user, Organization org,
|
||||
public async Task CreateAsync_Works_DataMatches(OrganizationUser orgUser, User user, Organization org,
|
||||
OrganizationUserCompare equalityComparer, List<EfRepo.OrganizationUserRepository> suts,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos, List<EfRepo.UserRepository> efUserRepos,
|
||||
SqlRepo.OrganizationUserRepository sqlOrgUserRepo, SqlRepo.UserRepository sqlUserRepo,
|
||||
@ -61,7 +61,7 @@ public class OrganizationUserRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationUserAutoData]
|
||||
public async void ReplaceAsync_Works_DataMatches(
|
||||
public async Task ReplaceAsync_Works_DataMatches(
|
||||
OrganizationUser postOrgUser,
|
||||
OrganizationUser replaceOrgUser,
|
||||
User user,
|
||||
@ -113,7 +113,7 @@ public class OrganizationUserRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationUserAutoData]
|
||||
public async void DeleteAsync_Works_DataMatches(OrganizationUser orgUser, User user, Organization org, List<EfRepo.OrganizationUserRepository> suts,
|
||||
public async Task DeleteAsync_Works_DataMatches(OrganizationUser orgUser, User user, Organization org, List<EfRepo.OrganizationUserRepository> suts,
|
||||
List<EfRepo.UserRepository> efUserRepos, List<EfRepo.OrganizationRepository> efOrgRepos,
|
||||
SqlRepo.OrganizationUserRepository sqlOrgUserRepo, SqlRepo.UserRepository sqlUserRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrgRepo)
|
||||
@ -166,7 +166,7 @@ public class OrganizationUserRepositoryTests
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, false)] // Policy disabled
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, true, false)] // No policy of Type
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Invited, true, false)] // User not minStatus
|
||||
public async void GetByUserIdWithPolicyDetailsAsync_Works_DataMatches(
|
||||
public async Task GetByUserIdWithPolicyDetailsAsync_Works_DataMatches(
|
||||
// Inline data
|
||||
OrganizationUserType userType,
|
||||
bool canManagePolicies,
|
||||
|
@ -14,7 +14,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.AdminConsole.Repositories;
|
||||
public class PolicyRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfPolicyAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(
|
||||
public async Task CreateAsync_Works_DataMatches(
|
||||
Policy policy,
|
||||
Organization organization,
|
||||
PolicyCompare equalityComparer,
|
||||
|
@ -15,7 +15,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Auth.Repositories;
|
||||
public class AuthRequestRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfAuthRequestAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(
|
||||
public async Task CreateAsync_Works_DataMatches(
|
||||
AuthRequest authRequest,
|
||||
AuthRequestCompare equalityComparer,
|
||||
List<EfAuthRepo.AuthRequestRepository> suts,
|
||||
|
@ -14,7 +14,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Auth.Repositories;
|
||||
public class EmergencyAccessRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfEmergencyAccessAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(
|
||||
public async Task CreateAsync_Works_DataMatches(
|
||||
EmergencyAccess emergencyAccess,
|
||||
List<User> users,
|
||||
EmergencyAccessCompare equalityComparer,
|
||||
|
@ -13,7 +13,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Auth.Repositories;
|
||||
public class SsoConfigRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfSsoConfigAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
|
||||
public async Task CreateAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
|
||||
SsoConfigCompare equalityComparer, List<EfRepo.SsoConfigRepository> suts,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos, SqlAuthRepo.SsoConfigRepository sqlSsoConfigRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo)
|
||||
@ -49,7 +49,7 @@ public class SsoConfigRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfSsoConfigAutoData]
|
||||
public async void ReplaceAsync_Works_DataMatches(SsoConfig postSsoConfig, SsoConfig replaceSsoConfig,
|
||||
public async Task ReplaceAsync_Works_DataMatches(SsoConfig postSsoConfig, SsoConfig replaceSsoConfig,
|
||||
Organization org, SsoConfigCompare equalityComparer, List<EfRepo.SsoConfigRepository> suts,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos, SqlAuthRepo.SsoConfigRepository sqlSsoConfigRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo)
|
||||
@ -94,7 +94,7 @@ public class SsoConfigRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfSsoConfigAutoData]
|
||||
public async void DeleteAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org, List<EfRepo.SsoConfigRepository> suts,
|
||||
public async Task DeleteAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org, List<EfRepo.SsoConfigRepository> suts,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos, SqlAuthRepo.SsoConfigRepository sqlSsoConfigRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo)
|
||||
{
|
||||
@ -131,7 +131,7 @@ public class SsoConfigRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfSsoConfigAutoData]
|
||||
public async void GetByOrganizationIdAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
|
||||
public async Task GetByOrganizationIdAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
|
||||
SsoConfigCompare equalityComparer, List<EfRepo.SsoConfigRepository> suts,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos, SqlAuthRepo.SsoConfigRepository sqlSsoConfigRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrgRepo)
|
||||
@ -168,7 +168,7 @@ public class SsoConfigRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfSsoConfigAutoData]
|
||||
public async void GetByIdentifierAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
|
||||
public async Task GetByIdentifierAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
|
||||
SsoConfigCompare equalityComparer, List<EfRepo.SsoConfigRepository> suts,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos, SqlAuthRepo.SsoConfigRepository sqlSsoConfigRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrgRepo)
|
||||
@ -206,7 +206,7 @@ public class SsoConfigRepositoryTests
|
||||
|
||||
// Testing that data matches here would involve manipulating all SsoConfig records in the db
|
||||
[CiSkippedTheory, EfSsoConfigAutoData]
|
||||
public async void GetManyByRevisionNotBeforeDate_Works(SsoConfig ssoConfig, DateTime notBeforeDate,
|
||||
public async Task GetManyByRevisionNotBeforeDate_Works(SsoConfig ssoConfig, DateTime notBeforeDate,
|
||||
Organization org, List<EfRepo.SsoConfigRepository> suts,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos)
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Auth.Repositories;
|
||||
public class SsoUserRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfSsoUserAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(SsoUser ssoUser, User user, Organization org,
|
||||
public async Task CreateAsync_Works_DataMatches(SsoUser ssoUser, User user, Organization org,
|
||||
SsoUserCompare equalityComparer, List<EfRepo.SsoUserRepository> suts,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos, List<EfRepo.UserRepository> efUserRepos,
|
||||
SqlAuthRepo.SsoUserRepository sqlSsoUserRepo, SqlRepo.OrganizationRepository sqlOrgRepo,
|
||||
@ -52,7 +52,7 @@ public class SsoUserRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfSsoUserAutoData]
|
||||
public async void ReplaceAsync_Works_DataMatches(SsoUser postSsoUser, SsoUser replaceSsoUser,
|
||||
public async Task ReplaceAsync_Works_DataMatches(SsoUser postSsoUser, SsoUser replaceSsoUser,
|
||||
Organization org, User user, SsoUserCompare equalityComparer,
|
||||
List<EfRepo.SsoUserRepository> suts, List<EfRepo.UserRepository> efUserRepos,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos, SqlAuthRepo.SsoUserRepository sqlSsoUserRepo,
|
||||
@ -101,7 +101,7 @@ public class SsoUserRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfSsoUserAutoData]
|
||||
public async void DeleteAsync_Works_DataMatches(SsoUser ssoUser, Organization org, User user, List<EfRepo.SsoUserRepository> suts,
|
||||
public async Task DeleteAsync_Works_DataMatches(SsoUser ssoUser, Organization org, User user, List<EfRepo.SsoUserRepository> suts,
|
||||
List<EfRepo.UserRepository> efUserRepos, List<EfRepo.OrganizationRepository> efOrgRepos,
|
||||
SqlAuthRepo.SsoUserRepository sqlSsoUserRepo, SqlRepo.UserRepository sqlUserRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo)
|
||||
@ -143,7 +143,7 @@ public class SsoUserRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfSsoUserAutoData]
|
||||
public async void DeleteAsync_UserIdOrganizationId_Works_DataMatches(SsoUser ssoUser,
|
||||
public async Task DeleteAsync_UserIdOrganizationId_Works_DataMatches(SsoUser ssoUser,
|
||||
User user, Organization org, List<EfRepo.SsoUserRepository> suts,
|
||||
List<EfRepo.UserRepository> efUserRepos, List<EfRepo.OrganizationRepository> efOrgRepos,
|
||||
SqlAuthRepo.SsoUserRepository sqlSsoUserRepo, SqlRepo.UserRepository sqlUserRepo, SqlRepo.OrganizationRepository sqlOrgRepo
|
||||
|
@ -14,7 +14,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Repositories;
|
||||
public class CollectionRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, BitAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(
|
||||
public async Task CreateAsync_Works_DataMatches(
|
||||
Collection collection,
|
||||
Organization organization,
|
||||
CollectionCompare equalityComparer,
|
||||
|
@ -11,7 +11,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Repositories;
|
||||
public class DeviceRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfDeviceAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(Device device, User user,
|
||||
public async Task CreateAsync_Works_DataMatches(Device device, User user,
|
||||
DeviceCompare equalityComparer, List<EfRepo.DeviceRepository> suts,
|
||||
List<EfRepo.UserRepository> efUserRepos, SqlRepo.DeviceRepository sqlDeviceRepo,
|
||||
SqlRepo.UserRepository sqlUserRepo)
|
||||
|
@ -11,7 +11,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Repositories;
|
||||
public class InstallationRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfInstallationAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(
|
||||
public async Task CreateAsync_Works_DataMatches(
|
||||
Installation installation,
|
||||
InstallationCompare equalityComparer,
|
||||
List<EfRepo.InstallationRepository> suts,
|
||||
|
@ -12,7 +12,7 @@ namespace Bit.Infrastructure.EFIntegration.Test.Repositories;
|
||||
public class OrganizationSponsorshipRepositoryTests
|
||||
{
|
||||
[CiSkippedTheory, EfOrganizationSponsorshipAutoData]
|
||||
public async void CreateAsync_Works_DataMatches(
|
||||
public async Task CreateAsync_Works_DataMatches(
|
||||
OrganizationSponsorship organizationSponsorship, Organization sponsoringOrg,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo,
|
||||
@ -47,7 +47,7 @@ public class OrganizationSponsorshipRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationSponsorshipAutoData]
|
||||
public async void ReplaceAsync_Works_DataMatches(OrganizationSponsorship postOrganizationSponsorship,
|
||||
public async Task ReplaceAsync_Works_DataMatches(OrganizationSponsorship postOrganizationSponsorship,
|
||||
OrganizationSponsorship replaceOrganizationSponsorship, Organization sponsoringOrg,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo,
|
||||
@ -89,7 +89,7 @@ public class OrganizationSponsorshipRepositoryTests
|
||||
}
|
||||
|
||||
[CiSkippedTheory, EfOrganizationSponsorshipAutoData]
|
||||
public async void DeleteAsync_Works_DataMatches(OrganizationSponsorship organizationSponsorship,
|
||||
public async Task DeleteAsync_Works_DataMatches(OrganizationSponsorship organizationSponsorship,
|
||||
Organization sponsoringOrg,
|
||||
List<EfRepo.OrganizationRepository> efOrgRepos,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user