mirror of
https://github.com/bitwarden/server
synced 2026-01-28 07:13:46 +00:00
Merge branch 'main' into billing/aspire
This commit is contained in:
117
.github/renovate.json5
vendored
117
.github/renovate.json5
vendored
@@ -10,42 +10,7 @@
|
||||
"nuget",
|
||||
],
|
||||
packageRules: [
|
||||
{
|
||||
groupName: "cargo minor",
|
||||
matchManagers: ["cargo"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
},
|
||||
{
|
||||
groupName: "dockerfile minor",
|
||||
matchManagers: ["dockerfile"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
},
|
||||
{
|
||||
groupName: "docker-compose minor",
|
||||
matchManagers: ["docker-compose"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
},
|
||||
{
|
||||
groupName: "github-action minor",
|
||||
matchManagers: ["github-actions"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
addLabels: ["hold"],
|
||||
},
|
||||
{
|
||||
// For any Microsoft.Extensions.* and Microsoft.AspNetCore.* packages, we want to create PRs for patch updates.
|
||||
// This overrides the default that ignores patch updates for nuget dependencies.
|
||||
matchPackageNames: [
|
||||
"/^Microsoft\\.Extensions\\./",
|
||||
"/^Microsoft\\.AspNetCore\\./",
|
||||
],
|
||||
matchUpdateTypes: ["patch"],
|
||||
dependencyDashboardApproval: false,
|
||||
},
|
||||
{
|
||||
matchPackageNames: ["https://github.com/bitwarden/sdk-internal.git"],
|
||||
groupName: "sdk-internal",
|
||||
dependencyDashboardApproval: true
|
||||
},
|
||||
// ==================== Team Ownership Rules ====================
|
||||
{
|
||||
matchManagers: ["dockerfile", "docker-compose"],
|
||||
commitMessagePrefix: "[deps] BRE:",
|
||||
@@ -68,6 +33,7 @@
|
||||
"Fido2.AspNet",
|
||||
"Duende.IdentityServer",
|
||||
"Microsoft.AspNetCore.Authentication.JwtBearer",
|
||||
"Microsoft.Extensions.Caching.Cosmos",
|
||||
"Microsoft.Extensions.Identity.Stores",
|
||||
"Otp.NET",
|
||||
"Sustainsys.Saml2.AspNetCore2",
|
||||
@@ -101,11 +67,6 @@
|
||||
commitMessagePrefix: "[deps] Billing:",
|
||||
reviewers: ["team:team-billing-dev"],
|
||||
},
|
||||
{
|
||||
matchPackageNames: ["/^Microsoft\\.EntityFrameworkCore\\./", "/^dotnet-ef/"],
|
||||
groupName: "EntityFrameworkCore",
|
||||
description: "Group EntityFrameworkCore to exclude them from the dotnet monorepo preset",
|
||||
},
|
||||
{
|
||||
matchPackageNames: [
|
||||
"Dapper",
|
||||
@@ -153,7 +114,6 @@
|
||||
"Microsoft.Extensions.DependencyInjection",
|
||||
"Microsoft.Extensions.Logging",
|
||||
"Microsoft.Extensions.Logging.Console",
|
||||
"Microsoft.Extensions.Caching.Cosmos",
|
||||
"Microsoft.Extensions.Caching.SqlServer",
|
||||
"Microsoft.Extensions.Caching.StackExchangeRedis",
|
||||
"Quartz",
|
||||
@@ -162,6 +122,12 @@
|
||||
commitMessagePrefix: "[deps] Platform:",
|
||||
reviewers: ["team:team-platform-dev"],
|
||||
},
|
||||
{
|
||||
matchUpdateTypes: ["lockFileMaintenance"],
|
||||
description: "Platform owns lock file maintenance",
|
||||
commitMessagePrefix: "[deps] Platform:",
|
||||
reviewers: ["team:team-platform-dev"],
|
||||
},
|
||||
{
|
||||
matchPackageNames: [
|
||||
"AutoMapper.Extensions.Microsoft.DependencyInjection",
|
||||
@@ -191,6 +157,73 @@
|
||||
commitMessagePrefix: "[deps] Vault:",
|
||||
reviewers: ["team:team-vault-dev"],
|
||||
},
|
||||
|
||||
// ==================== Grouping Rules ====================
|
||||
// These come after any specific team assignment rules to ensure
|
||||
// that grouping is not overridden by subsequent rule definitions.
|
||||
{
|
||||
groupName: "cargo minor",
|
||||
matchManagers: ["cargo"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
},
|
||||
{
|
||||
groupName: "dockerfile minor",
|
||||
matchManagers: ["dockerfile"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
},
|
||||
{
|
||||
groupName: "docker-compose minor",
|
||||
matchManagers: ["docker-compose"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
},
|
||||
{
|
||||
groupName: "github-action minor",
|
||||
matchManagers: ["github-actions"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
addLabels: ["hold"],
|
||||
},
|
||||
{
|
||||
matchPackageNames: ["/^Microsoft\\.EntityFrameworkCore\\./", "/^dotnet-ef/"],
|
||||
groupName: "EntityFrameworkCore",
|
||||
description: "Group EntityFrameworkCore to exclude them from the dotnet monorepo preset",
|
||||
},
|
||||
{
|
||||
matchPackageNames: ["https://github.com/bitwarden/sdk-internal.git"],
|
||||
groupName: "sdk-internal",
|
||||
dependencyDashboardApproval: true
|
||||
},
|
||||
|
||||
// ==================== Dashboard Rules ====================
|
||||
{
|
||||
// For any Microsoft.Extensions.* and Microsoft.AspNetCore.* packages, we want to create PRs for patch updates.
|
||||
// This overrides the default that ignores patch updates for nuget dependencies.
|
||||
matchPackageNames: [
|
||||
"/^Microsoft\\.Extensions\\./",
|
||||
"/^Microsoft\\.AspNetCore\\./",
|
||||
],
|
||||
matchUpdateTypes: ["patch"],
|
||||
dependencyDashboardApproval: false,
|
||||
},
|
||||
{
|
||||
// For the Platform-owned dependencies below, we have decided we will only be creating PRs
|
||||
// for major updates, and sending minor (as well as patch, inherited from base config) to the dashboard.
|
||||
// This rule comes AFTER grouping rules so that groups are respected while still
|
||||
// sending minor/patch updates to the dependency dashboard for approval.
|
||||
matchPackageNames: [
|
||||
"AspNetCoreRateLimit",
|
||||
"AspNetCoreRateLimit.Redis",
|
||||
"Azure.Data.Tables",
|
||||
"Azure.Extensions.AspNetCore.DataProtection.Blobs",
|
||||
"Azure.Messaging.EventGrid",
|
||||
"Azure.Messaging.ServiceBus",
|
||||
"Azure.Storage.Blobs",
|
||||
"Azure.Storage.Queues",
|
||||
"LaunchDarkly.ServerSdk",
|
||||
"Quartz",
|
||||
],
|
||||
matchUpdateTypes: ["minor"],
|
||||
dependencyDashboardApproval: true,
|
||||
},
|
||||
],
|
||||
ignoreDeps: ["dotnet-sdk"],
|
||||
}
|
||||
|
||||
30
.github/workflows/build.yml
vendored
30
.github/workflows/build.yml
vendored
@@ -123,7 +123,7 @@ jobs:
|
||||
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5.0.0
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "**/package-lock.json"
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
ls -atlh ../../../
|
||||
|
||||
- name: Upload project artifact
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
if: ${{ matrix.dotnet }}
|
||||
with:
|
||||
name: ${{ matrix.project_name }}.zip
|
||||
@@ -169,10 +169,10 @@ jobs:
|
||||
|
||||
########## Set up Docker ##########
|
||||
- name: Set up QEMU emulators
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
########## ACRs ##########
|
||||
- name: Log in to Azure
|
||||
@@ -246,7 +246,7 @@ jobs:
|
||||
|
||||
- name: Install Cosign
|
||||
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
||||
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
|
||||
uses: sigstore/cosign-installer@7e8b541eb2e61bf99390e1afd4be13a184e9ebc5 # v3.10.1
|
||||
|
||||
- name: Sign image with Cosign
|
||||
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
||||
@@ -264,7 +264,7 @@ jobs:
|
||||
|
||||
- name: Scan Docker image
|
||||
id: container-scan
|
||||
uses: anchore/scan-action@f6601287cdb1efc985d6b765bbf99cb4c0ac29d8 # v7.0.0
|
||||
uses: anchore/scan-action@3c9a191a0fbab285ca6b8530b5de5a642cba332f # v7.2.2
|
||||
with:
|
||||
image: ${{ steps.image-tags.outputs.primary_tag }}
|
||||
fail-build: false
|
||||
@@ -356,7 +356,7 @@ jobs:
|
||||
if: |
|
||||
github.event_name != 'pull_request'
|
||||
&& (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc')
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: docker-stub-US.zip
|
||||
path: docker-stub-US.zip
|
||||
@@ -366,7 +366,7 @@ jobs:
|
||||
if: |
|
||||
github.event_name != 'pull_request'
|
||||
&& (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc')
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: docker-stub-EU.zip
|
||||
path: docker-stub-EU.zip
|
||||
@@ -378,21 +378,21 @@ jobs:
|
||||
pwsh ./generate_openapi_files.ps1
|
||||
|
||||
- name: Upload Public API Swagger artifact
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: swagger.json
|
||||
path: api.public.json
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Internal API Swagger artifact
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: internal.json
|
||||
path: api.json
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Identity Swagger artifact
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: identity.json
|
||||
path: identity.json
|
||||
@@ -438,7 +438,7 @@ jobs:
|
||||
|
||||
- name: Upload project artifact for Windows
|
||||
if: ${{ contains(matrix.target, 'win') == true }}
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: MsSqlMigratorUtility-${{ matrix.target }}
|
||||
path: util/MsSqlMigratorUtility/obj/build-output/publish/MsSqlMigratorUtility.exe
|
||||
@@ -446,7 +446,7 @@ jobs:
|
||||
|
||||
- name: Upload project artifact
|
||||
if: ${{ contains(matrix.target, 'win') == false }}
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: MsSqlMigratorUtility-${{ matrix.target }}
|
||||
path: util/MsSqlMigratorUtility/obj/build-output/publish/MsSqlMigratorUtility
|
||||
@@ -481,7 +481,7 @@ jobs:
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
|
||||
@@ -531,7 +531,7 @@ jobs:
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
|
||||
|
||||
2
.github/workflows/code-references.yml
vendored
2
.github/workflows/code-references.yml
vendored
@@ -59,7 +59,7 @@ jobs:
|
||||
|
||||
- name: Collect
|
||||
id: collect
|
||||
uses: launchdarkly/find-code-references@e3e9da201b87ada54eb4c550c14fb783385c5c8a # v2.13.0
|
||||
uses: launchdarkly/find-code-references@89a7d362d1d4b3725fe0fe0ccd0dc69e3bdcba58 # v2.14.0
|
||||
with:
|
||||
accessToken: ${{ steps.get-kv-secrets.outputs.LD-ACCESS-TOKEN }}
|
||||
projKey: default
|
||||
|
||||
2
.github/workflows/load-test.yml
vendored
2
.github/workflows/load-test.yml
vendored
@@ -95,7 +95,7 @@ jobs:
|
||||
uses: grafana/setup-k6-action@ffe7d7290dfa715e48c2ccc924d068444c94bde2 # v1.1.0
|
||||
|
||||
- name: Run k6 tests
|
||||
uses: grafana/run-k6-action@c6b79182b9b666aa4f630f4a6be9158ead62536e # v1.2.0
|
||||
uses: grafana/run-k6-action@a15e2072ede004e8d46141e33d7f7dad8ad08d9d # v1.3.1
|
||||
continue-on-error: false
|
||||
env:
|
||||
K6_OTEL_METRIC_PREFIX: k6_
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -89,7 +89,7 @@ jobs:
|
||||
|
||||
- name: Create release
|
||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1.16.0
|
||||
uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1.20.0
|
||||
with:
|
||||
artifacts: "docker-stub-US.zip,
|
||||
docker-stub-EU.zip,
|
||||
|
||||
4
.github/workflows/repository-management.yml
vendored
4
.github/workflows/repository-management.yml
vendored
@@ -83,7 +83,7 @@ jobs:
|
||||
version: ${{ inputs.version_number_override }}
|
||||
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
|
||||
@@ -207,7 +207,7 @@ jobs:
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
|
||||
|
||||
2
.github/workflows/review-code.yml
vendored
2
.github/workflows/review-code.yml
vendored
@@ -2,7 +2,7 @@ name: Code Review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
permissions: {}
|
||||
|
||||
|
||||
8
.github/workflows/test-database.yml
vendored
8
.github/workflows/test-database.yml
vendored
@@ -156,7 +156,7 @@ jobs:
|
||||
run: 'docker logs "$(docker ps --quiet --filter "name=mssql")"'
|
||||
|
||||
- name: Report test results
|
||||
uses: dorny/test-reporter@890a17cecf52a379fc869ab770a71657660be727 # v2.1.0
|
||||
uses: dorny/test-reporter@fe45e9537387dac839af0d33ba56eed8e24189e8 # v2.3.0
|
||||
if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !cancelled() }}
|
||||
with:
|
||||
name: Test Results
|
||||
@@ -165,7 +165,7 @@ jobs:
|
||||
fail-on-error: true
|
||||
|
||||
- name: Upload to codecov.io
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
|
||||
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||
|
||||
- name: Docker Compose down
|
||||
if: always()
|
||||
@@ -197,7 +197,7 @@ jobs:
|
||||
shell: pwsh
|
||||
|
||||
- name: Upload DACPAC
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: sql.dacpac
|
||||
path: Sql.dacpac
|
||||
@@ -223,7 +223,7 @@ jobs:
|
||||
shell: pwsh
|
||||
|
||||
- name: Report validation results
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: report.xml
|
||||
path: |
|
||||
|
||||
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
toolchain: stable
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: Swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2.7.7
|
||||
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
run: dotnet test ./bitwarden_license/test --configuration Debug --logger "trx;LogFileName=bw-test-results.trx" /p:CoverletOutputFormatter="cobertura" --collect:"XPlat Code Coverage"
|
||||
|
||||
- name: Report test results
|
||||
uses: dorny/test-reporter@890a17cecf52a379fc869ab770a71657660be727 # v2.1.0
|
||||
uses: dorny/test-reporter@fe45e9537387dac839af0d33ba56eed8e24189e8 # v2.3.0
|
||||
if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !cancelled() }}
|
||||
with:
|
||||
name: Test Results
|
||||
@@ -68,4 +68,4 @@ jobs:
|
||||
fail-on-error: true
|
||||
|
||||
- name: Upload to codecov.io
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
|
||||
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||
|
||||
36
README.md
36
README.md
@@ -58,6 +58,42 @@ Invoke-RestMethod -OutFile bitwarden.ps1 `
|
||||
.\bitwarden.ps1 -start
|
||||
```
|
||||
|
||||
## Production Container Images
|
||||
|
||||
<details>
|
||||
<summary><b>View Current Production Image Hashes</b> (click to expand)</summary>
|
||||
<br>
|
||||
|
||||
### US Production Cluster
|
||||
|
||||
| Service | Image Hash |
|
||||
|---------|------------|
|
||||
| **Admin** |  |
|
||||
| **API** |  |
|
||||
| **Billing** |  |
|
||||
| **Events** |  |
|
||||
| **EventsProcessor** |  |
|
||||
| **Identity** |  |
|
||||
| **Notifications** |  |
|
||||
| **SCIM** |  |
|
||||
| **SSO** |  |
|
||||
|
||||
### EU Production Cluster
|
||||
|
||||
| Service | Image Hash |
|
||||
|---------|------------|
|
||||
| **Admin** |  |
|
||||
| **API** |  |
|
||||
| **Billing** |  |
|
||||
| **Events** |  |
|
||||
| **EventsProcessor** |  |
|
||||
| **Identity** |  |
|
||||
| **Notifications** |  |
|
||||
| **SCIM** |  |
|
||||
| **SSO** |  |
|
||||
|
||||
</details>
|
||||
|
||||
## We're Hiring!
|
||||
|
||||
Interested in contributing in a big way? Consider joining our team! We're hiring for many positions. Please take a look at our [Careers page](https://bitwarden.com/careers/) to see what opportunities are currently open as well as what it's like to work at Bitwarden.
|
||||
|
||||
@@ -57,8 +57,7 @@ public class ProviderClientsController(
|
||||
Owner = user,
|
||||
BillingEmail = provider.BillingEmail,
|
||||
OwnerKey = requestBody.Key,
|
||||
PublicKey = requestBody.KeyPair.PublicKey,
|
||||
PrivateKey = requestBody.KeyPair.EncryptedPrivateKey,
|
||||
Keys = requestBody.KeyPair.ToPublicKeyEncryptionKeyPairData(),
|
||||
CollectionName = requestBody.CollectionName,
|
||||
IsFromProvider = true
|
||||
};
|
||||
|
||||
@@ -113,11 +113,10 @@ public class OrganizationCreateRequestModel : IValidatableObject
|
||||
BillingAddressCountry = BillingAddressCountry,
|
||||
},
|
||||
InitiationPath = InitiationPath,
|
||||
SkipTrial = SkipTrial
|
||||
SkipTrial = SkipTrial,
|
||||
Keys = Keys?.ToPublicKeyEncryptionKeyPairData()
|
||||
};
|
||||
|
||||
Keys?.ToOrganizationSignup(orgSignup);
|
||||
|
||||
return orgSignup;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#nullable disable
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.KeyManagement.Models.Data;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
|
||||
@@ -14,48 +13,10 @@ public class OrganizationKeysRequestModel
|
||||
[Required]
|
||||
public string EncryptedPrivateKey { get; set; }
|
||||
|
||||
public OrganizationSignup ToOrganizationSignup(OrganizationSignup existingSignup)
|
||||
public PublicKeyEncryptionKeyPairData ToPublicKeyEncryptionKeyPairData()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingSignup.PublicKey))
|
||||
{
|
||||
existingSignup.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingSignup.PrivateKey))
|
||||
{
|
||||
existingSignup.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingSignup;
|
||||
}
|
||||
|
||||
public OrganizationUpgrade ToOrganizationUpgrade(OrganizationUpgrade existingUpgrade)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingUpgrade.PublicKey))
|
||||
{
|
||||
existingUpgrade.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingUpgrade.PrivateKey))
|
||||
{
|
||||
existingUpgrade.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingUpgrade;
|
||||
}
|
||||
|
||||
public Organization ToOrganization(Organization existingOrg)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingOrg.PublicKey))
|
||||
{
|
||||
existingOrg.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingOrg.PrivateKey))
|
||||
{
|
||||
existingOrg.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingOrg;
|
||||
return new PublicKeyEncryptionKeyPairData(
|
||||
wrappedPrivateKey: EncryptedPrivateKey,
|
||||
publicKey: PublicKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,10 +110,9 @@ public class OrganizationNoPaymentCreateRequest
|
||||
BillingAddressCountry = BillingAddressCountry,
|
||||
},
|
||||
InitiationPath = InitiationPath,
|
||||
Keys = Keys?.ToPublicKeyEncryptionKeyPairData()
|
||||
};
|
||||
|
||||
Keys?.ToOrganizationSignup(orgSignup);
|
||||
|
||||
return orgSignup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ public class OrganizationUpdateRequestModel
|
||||
OrganizationId = organizationId,
|
||||
Name = Name,
|
||||
BillingEmail = BillingEmail,
|
||||
PublicKey = Keys?.PublicKey,
|
||||
EncryptedPrivateKey = Keys?.EncryptedPrivateKey
|
||||
Keys = Keys?.ToPublicKeyEncryptionKeyPairData()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,11 +43,10 @@ public class OrganizationUpgradeRequestModel
|
||||
{
|
||||
BillingAddressCountry = BillingAddressCountry,
|
||||
BillingAddressPostalCode = BillingAddressPostalCode
|
||||
}
|
||||
},
|
||||
Keys = Keys?.ToPublicKeyEncryptionKeyPairData()
|
||||
};
|
||||
|
||||
Keys?.ToOrganizationUpgrade(orgUpgrade);
|
||||
|
||||
return orgUpgrade;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="8.0.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="8.0.1" />
|
||||
<PackageReference Include="Azure.Messaging.EventGrid" Version="4.31.0" />
|
||||
<PackageReference Include="Azure.Messaging.EventGrid" Version="5.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ using Microsoft.AspNetCore.Mvc;
|
||||
namespace Bit.Api.Auth.Controllers;
|
||||
|
||||
[Route("webauthn")]
|
||||
[Authorize(Policies.Web)]
|
||||
public class WebAuthnController : Controller
|
||||
{
|
||||
private readonly IUserService _userService;
|
||||
@@ -62,6 +61,7 @@ public class WebAuthnController : Controller
|
||||
_featureService = featureService;
|
||||
}
|
||||
|
||||
[Authorize(Policies.Web)]
|
||||
[HttpGet("")]
|
||||
public async Task<ListResponseModel<WebAuthnCredentialResponseModel>> Get()
|
||||
{
|
||||
@@ -71,6 +71,7 @@ public class WebAuthnController : Controller
|
||||
return new ListResponseModel<WebAuthnCredentialResponseModel>(credentials.Select(c => new WebAuthnCredentialResponseModel(c)));
|
||||
}
|
||||
|
||||
[Authorize(Policies.Application)]
|
||||
[HttpPost("attestation-options")]
|
||||
public async Task<WebAuthnCredentialCreateOptionsResponseModel> AttestationOptions([FromBody] SecretVerificationRequestModel model)
|
||||
{
|
||||
@@ -88,6 +89,7 @@ public class WebAuthnController : Controller
|
||||
};
|
||||
}
|
||||
|
||||
[Authorize(Policies.Web)]
|
||||
[HttpPost("assertion-options")]
|
||||
public async Task<WebAuthnLoginAssertionOptionsResponseModel> AssertionOptions([FromBody] SecretVerificationRequestModel model)
|
||||
{
|
||||
@@ -104,6 +106,7 @@ public class WebAuthnController : Controller
|
||||
};
|
||||
}
|
||||
|
||||
[Authorize(Policies.Application)]
|
||||
[HttpPost("")]
|
||||
public async Task Post([FromBody] WebAuthnLoginCredentialCreateRequestModel model)
|
||||
{
|
||||
@@ -149,6 +152,7 @@ public class WebAuthnController : Controller
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize(Policies.Application)]
|
||||
[HttpPut()]
|
||||
public async Task UpdateCredential([FromBody] WebAuthnLoginCredentialUpdateRequestModel model)
|
||||
{
|
||||
@@ -172,6 +176,7 @@ public class WebAuthnController : Controller
|
||||
await _credentialRepository.UpdateAsync(credential);
|
||||
}
|
||||
|
||||
[Authorize(Policies.Web)]
|
||||
[HttpPost("{id}/delete")]
|
||||
public async Task Delete(Guid id, [FromBody] SecretVerificationRequestModel model)
|
||||
{
|
||||
|
||||
@@ -273,7 +273,7 @@ public class TwoFactorWebAuthnDeleteRequestModel : SecretVerificationRequestMode
|
||||
yield return validationResult;
|
||||
}
|
||||
|
||||
if (!Id.HasValue || Id < 0 || Id > 5)
|
||||
if (!Id.HasValue)
|
||||
{
|
||||
yield return new ValidationResult("Invalid Key Id", new string[] { nameof(Id) });
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Bit.Api.Billing.Models.Requests.Payment;
|
||||
using Bit.Api.Billing.Models.Requests.Premium;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Billing.Licenses.Queries;
|
||||
using Bit.Core.Billing.Payment.Commands;
|
||||
using Bit.Core.Billing.Payment.Queries;
|
||||
using Bit.Core.Billing.Premium.Commands;
|
||||
@@ -21,6 +22,7 @@ public class AccountBillingVNextController(
|
||||
ICreatePremiumCloudHostedSubscriptionCommand createPremiumCloudHostedSubscriptionCommand,
|
||||
IGetCreditQuery getCreditQuery,
|
||||
IGetPaymentMethodQuery getPaymentMethodQuery,
|
||||
IGetUserLicenseQuery getUserLicenseQuery,
|
||||
IUpdatePaymentMethodCommand updatePaymentMethodCommand) : BaseBillingController
|
||||
{
|
||||
[HttpGet("credit")]
|
||||
@@ -77,4 +79,13 @@ public class AccountBillingVNextController(
|
||||
user, paymentMethod, billingAddress, additionalStorageGb);
|
||||
return Handle(result);
|
||||
}
|
||||
|
||||
[HttpGet("license")]
|
||||
[InjectUser]
|
||||
public async Task<IResult> GetLicenseAsync(
|
||||
[BindNever] User user)
|
||||
{
|
||||
var response = await getUserLicenseQuery.Run(user);
|
||||
return TypedResults.Ok(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#nullable disable
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.KeyManagement.Models.Data;
|
||||
|
||||
namespace Bit.Api.Billing.Models.Requests;
|
||||
|
||||
@@ -12,4 +13,11 @@ public class KeyPairRequestBody
|
||||
public string PublicKey { get; set; }
|
||||
[Required(ErrorMessage = "'encryptedPrivateKey' must be provided")]
|
||||
public string EncryptedPrivateKey { get; set; }
|
||||
|
||||
public PublicKeyEncryptionKeyPairData ToPublicKeyEncryptionKeyPairData()
|
||||
{
|
||||
return new PublicKeyEncryptionKeyPairData(
|
||||
wrappedPrivateKey: EncryptedPrivateKey,
|
||||
publicKey: PublicKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Api.Dirt.Models.Request;
|
||||
using Bit.Api.Dirt.Models.Response;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.Exceptions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Controllers;
|
||||
namespace Bit.Api.Dirt.Controllers;
|
||||
|
||||
[Route("organizations/{organizationId:guid}/integrations/{integrationId:guid}/configurations")]
|
||||
[Authorize("Application")]
|
||||
@@ -1,12 +1,12 @@
|
||||
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Api.Dirt.Models.Request;
|
||||
using Bit.Api.Dirt.Models.Response;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Exceptions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Controllers;
|
||||
namespace Bit.Api.Dirt.Controllers;
|
||||
|
||||
[Route("organizations/{organizationId:guid}/integrations")]
|
||||
[Authorize("Application")]
|
||||
@@ -1,16 +1,16 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
using Bit.Api.Dirt.Models.Response;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Dirt.Services;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Controllers;
|
||||
namespace Bit.Api.Dirt.Controllers;
|
||||
|
||||
[Route("organizations")]
|
||||
[Authorize("Application")]
|
||||
@@ -1,18 +1,18 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
using Bit.Api.Dirt.Models.Response;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Dirt.Services;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Bot.Builder;
|
||||
using Microsoft.Bot.Builder.Integration.AspNet.Core;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Controllers;
|
||||
namespace Bit.Api.Dirt.Controllers;
|
||||
|
||||
[Route("organizations")]
|
||||
[Authorize("Application")]
|
||||
@@ -1,8 +1,7 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
|
||||
namespace Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
namespace Bit.Api.Dirt.Models.Request;
|
||||
|
||||
public class OrganizationIntegrationConfigurationRequestModel
|
||||
{
|
||||
@@ -1,10 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
namespace Bit.Api.Dirt.Models.Request;
|
||||
|
||||
public class OrganizationIntegrationRequestModel : IValidatableObject
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
namespace Bit.Api.Dirt.Models.Response;
|
||||
|
||||
public class OrganizationIntegrationConfigurationResponseModel : ResponseModel
|
||||
{
|
||||
@@ -1,10 +1,10 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
using Bit.Core.Models.Api;
|
||||
|
||||
namespace Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
namespace Bit.Api.Dirt.Models.Response;
|
||||
|
||||
public class OrganizationIntegrationResponseModel : ResponseModel
|
||||
{
|
||||
@@ -1,6 +1,7 @@
|
||||
// FIXME: Update this file to be null safe and then delete the line below
|
||||
#nullable disable
|
||||
|
||||
using Bit.Core;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Services;
|
||||
@@ -45,7 +46,8 @@ public class ConfigResponseModel : ResponseModel
|
||||
Sso = globalSettings.BaseServiceUri.Sso
|
||||
};
|
||||
FeatureStates = featureService.GetAll();
|
||||
Push = PushSettings.Build(globalSettings);
|
||||
var webPushEnabled = FeatureStates.TryGetValue(FeatureFlagKeys.WebPush, out var webPushEnabledValue) ? (bool)webPushEnabledValue : false;
|
||||
Push = PushSettings.Build(webPushEnabled, globalSettings);
|
||||
Settings = new ServerSettingsResponseModel
|
||||
{
|
||||
DisableUserRegistration = globalSettings.DisableUserRegistration
|
||||
@@ -74,9 +76,9 @@ public class PushSettings
|
||||
public PushTechnologyType PushTechnology { get; private init; }
|
||||
public string VapidPublicKey { get; private init; }
|
||||
|
||||
public static PushSettings Build(IGlobalSettings globalSettings)
|
||||
public static PushSettings Build(bool webPushEnabled, IGlobalSettings globalSettings)
|
||||
{
|
||||
var vapidPublicKey = globalSettings.WebPush.VapidPublicKey;
|
||||
var vapidPublicKey = webPushEnabled ? globalSettings.WebPush.VapidPublicKey : null;
|
||||
var pushTechnology = vapidPublicKey != null ? PushTechnologyType.WebPush : PushTechnologyType.SignalR;
|
||||
return new()
|
||||
{
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
|
||||
public record DatadogIntegration(string ApiKey, Uri Uri);
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
|
||||
public record SlackIntegration(string Token);
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
|
||||
public record SlackIntegrationConfiguration(string ChannelId);
|
||||
@@ -99,8 +99,8 @@ public class CloudOrganizationSignUpCommand(
|
||||
ReferenceData = signup.Owner.ReferenceData,
|
||||
Enabled = true,
|
||||
LicenseKey = CoreHelpers.SecureRandomString(20),
|
||||
PublicKey = signup.PublicKey,
|
||||
PrivateKey = signup.PrivateKey,
|
||||
PublicKey = signup.Keys?.PublicKey,
|
||||
PrivateKey = signup.Keys?.WrappedPrivateKey,
|
||||
CreationDate = DateTime.UtcNow,
|
||||
RevisionDate = DateTime.UtcNow,
|
||||
Status = OrganizationStatusType.Created,
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.KeyManagement.Models.Data;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
|
||||
|
||||
public static class OrganizationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the organization public and private keys if provided and not already set.
|
||||
/// This is legacy code for old organizations that were not created with a public/private keypair.
|
||||
/// It is a soft migration that will silently migrate organizations when they perform certain actions,
|
||||
/// e.g. change their details or upgrade their plan.
|
||||
/// </summary>
|
||||
public static void BackfillPublicPrivateKeys(this Organization organization, PublicKeyEncryptionKeyPairData? keyPair)
|
||||
{
|
||||
// Only backfill if both new keys are provided and both old keys are missing.
|
||||
if (string.IsNullOrWhiteSpace(keyPair?.PublicKey) ||
|
||||
string.IsNullOrWhiteSpace(keyPair.WrappedPrivateKey) ||
|
||||
!string.IsNullOrWhiteSpace(organization.PublicKey) ||
|
||||
!string.IsNullOrWhiteSpace(organization.PrivateKey))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
organization.PublicKey = keyPair.PublicKey;
|
||||
organization.PrivateKey = keyPair.WrappedPrivateKey;
|
||||
}
|
||||
}
|
||||
@@ -93,8 +93,8 @@ public class ProviderClientOrganizationSignUpCommand : IProviderClientOrganizati
|
||||
ReferenceData = signup.Owner.ReferenceData,
|
||||
Enabled = true,
|
||||
LicenseKey = CoreHelpers.SecureRandomString(20),
|
||||
PublicKey = signup.PublicKey,
|
||||
PrivateKey = signup.PrivateKey,
|
||||
PublicKey = signup.Keys?.PublicKey,
|
||||
PrivateKey = signup.Keys?.WrappedPrivateKey,
|
||||
CreationDate = DateTime.UtcNow,
|
||||
RevisionDate = DateTime.UtcNow,
|
||||
Status = OrganizationStatusType.Created,
|
||||
|
||||
@@ -39,8 +39,20 @@ public class OrganizationUpdateCommand(
|
||||
var originalBillingEmail = organization.BillingEmail;
|
||||
|
||||
// Apply updates to organization
|
||||
organization.UpdateDetails(request);
|
||||
organization.BackfillPublicPrivateKeys(request);
|
||||
// These values may or may not be sent by the client depending on the operation being performed.
|
||||
// Skip any values not provided.
|
||||
if (request.Name is not null)
|
||||
{
|
||||
organization.Name = request.Name;
|
||||
}
|
||||
|
||||
if (request.BillingEmail is not null)
|
||||
{
|
||||
organization.BillingEmail = request.BillingEmail.ToLowerInvariant().Trim();
|
||||
}
|
||||
|
||||
organization.BackfillPublicPrivateKeys(request.Keys);
|
||||
|
||||
await organizationService.ReplaceAndUpdateCacheAsync(organization, EventType.Organization_Updated);
|
||||
|
||||
// Update billing information in Stripe if required
|
||||
@@ -56,7 +68,7 @@ public class OrganizationUpdateCommand(
|
||||
/// </summary>
|
||||
private async Task<Organization> UpdateSelfHostedAsync(Organization organization, OrganizationUpdateRequest request)
|
||||
{
|
||||
organization.BackfillPublicPrivateKeys(request);
|
||||
organization.BackfillPublicPrivateKeys(request.Keys);
|
||||
await organizationService.ReplaceAndUpdateCacheAsync(organization, EventType.Organization_Updated);
|
||||
return organization;
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Update;
|
||||
|
||||
public static class OrganizationUpdateExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the organization name and/or billing email.
|
||||
/// Any null property on the request object will be skipped.
|
||||
/// </summary>
|
||||
public static void UpdateDetails(this Organization organization, OrganizationUpdateRequest request)
|
||||
{
|
||||
// These values may or may not be sent by the client depending on the operation being performed.
|
||||
// Skip any values not provided.
|
||||
if (request.Name is not null)
|
||||
{
|
||||
organization.Name = request.Name;
|
||||
}
|
||||
|
||||
if (request.BillingEmail is not null)
|
||||
{
|
||||
organization.BillingEmail = request.BillingEmail.ToLowerInvariant().Trim();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the organization public and private keys if provided and not already set.
|
||||
/// This is legacy code for old organizations that were not created with a public/private keypair. It is a soft
|
||||
/// migration that will silently migrate organizations when they change their details.
|
||||
/// </summary>
|
||||
public static void BackfillPublicPrivateKeys(this Organization organization, OrganizationUpdateRequest request)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(request.PublicKey) && string.IsNullOrWhiteSpace(organization.PublicKey))
|
||||
{
|
||||
organization.PublicKey = request.PublicKey;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.EncryptedPrivateKey) && string.IsNullOrWhiteSpace(organization.PrivateKey))
|
||||
{
|
||||
organization.PrivateKey = request.EncryptedPrivateKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Update;
|
||||
using Bit.Core.KeyManagement.Models.Data;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Update;
|
||||
|
||||
/// <summary>
|
||||
/// Request model for updating the name, billing email, and/or public-private keys for an organization (legacy migration code).
|
||||
@@ -22,12 +24,7 @@ public record OrganizationUpdateRequest
|
||||
public string? BillingEmail { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The organization's public key to set (optional, only set if not already present on the organization).
|
||||
/// The organization's public/private key pair to set (optional, only set if not already present on the organization).
|
||||
/// </summary>
|
||||
public string? PublicKey { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The organization's encrypted private key to set (optional, only set if not already present on the organization).
|
||||
/// </summary>
|
||||
public string? EncryptedPrivateKey { get; init; }
|
||||
public PublicKeyEncryptionKeyPairData? Keys { get; init; }
|
||||
}
|
||||
|
||||
@@ -72,6 +72,17 @@ public class OrganizationDataOwnershipPolicyRequirement : IPolicyRequirement
|
||||
{
|
||||
return _policyDetails.Any(p => p.OrganizationId == organizationId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore storage limits if the organization has data ownership policy enabled.
|
||||
/// Allows users to seamlessly migrate their data into the organization without being blocked by storage limits.
|
||||
/// Organization admins will need to manage storage after migration should overages occur.
|
||||
/// </summary>
|
||||
public bool IgnoreStorageLimitsOnMigration(Guid organizationId)
|
||||
{
|
||||
return _policyDetails.Any(p => p.OrganizationId == organizationId &&
|
||||
p.OrganizationUserStatus == OrganizationUserStatusType.Confirmed);
|
||||
}
|
||||
}
|
||||
|
||||
public record DefaultCollectionRequest(Guid OrganizationUserId, bool ShouldCreateDefaultCollection)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#nullable enable
|
||||
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data.Organizations;
|
||||
|
||||
namespace Bit.Core.Services;
|
||||
|
||||
public interface IIntegrationConfigurationDetailsCache
|
||||
{
|
||||
List<OrganizationIntegrationConfigurationDetails> GetConfigurationDetails(
|
||||
Guid organizationId,
|
||||
IntegrationType integrationType,
|
||||
EventType eventType);
|
||||
}
|
||||
@@ -5,12 +5,94 @@ public static class Policies
|
||||
/// <summary>
|
||||
/// Policy for managing access to the Send feature.
|
||||
/// </summary>
|
||||
public const string Send = "Send"; // [Authorize(Policy = Policies.Send)]
|
||||
public const string Application = "Application"; // [Authorize(Policy = Policies.Application)]
|
||||
public const string Web = "Web"; // [Authorize(Policy = Policies.Web)]
|
||||
public const string Push = "Push"; // [Authorize(Policy = Policies.Push)]
|
||||
/// <remarks>
|
||||
/// <example>
|
||||
/// Can be used with the <c>Authorize</c> attribute, for example:
|
||||
/// <code>
|
||||
/// [Authorize(Policy = Policies.Send)]
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public const string Send = "Send";
|
||||
|
||||
/// <summary>
|
||||
/// Policy to manage access to general API endpoints.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <example>
|
||||
/// Can be used with the <c>Authorize</c> attribute, for example:
|
||||
/// <code>
|
||||
/// [Authorize(Policy = Policies.Application)]
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public const string Application = "Application";
|
||||
|
||||
/// <summary>
|
||||
/// Policy to manage access to API endpoints intended for use by the Web Vault and browser extension only.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <example>
|
||||
/// Can be used with the <c>Authorize</c> attribute, for example:
|
||||
/// <code>
|
||||
/// [Authorize(Policy = Policies.Web)]
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public const string Web = "Web";
|
||||
|
||||
/// <summary>
|
||||
/// Policy to restrict access to API endpoints for the Push feature.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <example>
|
||||
/// Can be used with the <c>Authorize</c> attribute, for example:
|
||||
/// <code>
|
||||
/// [Authorize(Policy = Policies.Push)]
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public const string Push = "Push";
|
||||
|
||||
// TODO: This is unused
|
||||
public const string Licensing = "Licensing"; // [Authorize(Policy = Policies.Licensing)]
|
||||
public const string Organization = "Organization"; // [Authorize(Policy = Policies.Organization)]
|
||||
public const string Installation = "Installation"; // [Authorize(Policy = Policies.Installation)]
|
||||
public const string Secrets = "Secrets"; // [Authorize(Policy = Policies.Secrets)]
|
||||
|
||||
/// <summary>
|
||||
/// Policy to restrict access to API endpoints related to the Organization features.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <example>
|
||||
/// Can be used with the <c>Authorize</c> attribute, for example:
|
||||
/// <code>
|
||||
/// [Authorize(Policy = Policies.Licensing)]
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public const string Organization = "Organization";
|
||||
|
||||
/// <summary>
|
||||
/// Policy to restrict access to API endpoints related to the setting up new installations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <example>
|
||||
/// Can be used with the <c>Authorize</c> attribute, for example:
|
||||
/// <code>
|
||||
/// [Authorize(Policy = Policies.Installation)]
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public const string Installation = "Installation";
|
||||
|
||||
/// <summary>
|
||||
/// Policy to restrict access to API endpoints for Secrets Manager features.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <example>
|
||||
/// Can be used with the <c>Authorize</c> attribute, for example:
|
||||
/// <code>
|
||||
/// [Authorize(Policy = Policies.Secrets)]
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public const string Secrets = "Secrets";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Bit.Core.Billing.Caches;
|
||||
using Bit.Core.Billing.Caches.Implementations;
|
||||
using Bit.Core.Billing.Licenses;
|
||||
using Bit.Core.Billing.Licenses.Extensions;
|
||||
using Bit.Core.Billing.Organizations.Commands;
|
||||
using Bit.Core.Billing.Organizations.Queries;
|
||||
@@ -28,6 +29,7 @@ public static class ServiceCollectionExtensions
|
||||
services.AddTransient<ISetupIntentCache, SetupIntentDistributedCache>();
|
||||
services.AddTransient<ISubscriberService, SubscriberService>();
|
||||
services.AddLicenseServices();
|
||||
services.AddLicenseOperations();
|
||||
services.AddPricingClient();
|
||||
services.AddPaymentOperations();
|
||||
services.AddOrganizationLicenseCommandsQueries();
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Security.Claims;
|
||||
using Bit.Core.Billing.Licenses.Extensions;
|
||||
using Bit.Core.Billing.Models.Business;
|
||||
using Bit.Core.Models.Api;
|
||||
|
||||
namespace Bit.Core.Billing.Licenses.Models.Api.Response;
|
||||
|
||||
/// <summary>
|
||||
/// Response model containing user license information.
|
||||
/// Separated from subscription data to maintain separation of concerns.
|
||||
/// </summary>
|
||||
public class LicenseResponseModel : ResponseModel
|
||||
{
|
||||
public LicenseResponseModel(UserLicense license, ClaimsPrincipal? claimsPrincipal)
|
||||
: base("license")
|
||||
{
|
||||
License = license;
|
||||
|
||||
// CRITICAL: When a license has a Token (JWT), ALWAYS use the expiration from the token claim
|
||||
// The token's expiration is cryptographically secured and cannot be tampered with
|
||||
// The file's Expires property can be manually edited and should NOT be trusted for display
|
||||
if (claimsPrincipal != null)
|
||||
{
|
||||
Expiration = claimsPrincipal.GetValue<DateTime?>(UserLicenseConstants.Expires);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No token - use the license file expiration (for older licenses without tokens)
|
||||
Expiration = license.Expires;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The user's license containing feature entitlements and metadata.
|
||||
/// </summary>
|
||||
public UserLicense License { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The license expiration date.
|
||||
/// Extracted from the cryptographically secured JWT token when available,
|
||||
/// otherwise falls back to the license file's expiration date.
|
||||
/// </summary>
|
||||
public DateTime? Expiration { get; set; }
|
||||
}
|
||||
23
src/Core/Billing/Licenses/Queries/GetUserLicenseQuery.cs
Normal file
23
src/Core/Billing/Licenses/Queries/GetUserLicenseQuery.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Bit.Core.Billing.Licenses.Models.Api.Response;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Services;
|
||||
|
||||
namespace Bit.Core.Billing.Licenses.Queries;
|
||||
|
||||
public interface IGetUserLicenseQuery
|
||||
{
|
||||
Task<LicenseResponseModel> Run(User user);
|
||||
}
|
||||
|
||||
public class GetUserLicenseQuery(
|
||||
IUserService userService,
|
||||
ILicensingService licensingService) : IGetUserLicenseQuery
|
||||
{
|
||||
public async Task<LicenseResponseModel> Run(User user)
|
||||
{
|
||||
var license = await userService.GenerateLicenseAsync(user);
|
||||
var claimsPrincipal = licensingService.GetClaimsPrincipalFromLicense(license);
|
||||
return new LicenseResponseModel(license, claimsPrincipal);
|
||||
}
|
||||
}
|
||||
13
src/Core/Billing/Licenses/Registrations.cs
Normal file
13
src/Core/Billing/Licenses/Registrations.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Bit.Core.Billing.Licenses.Queries;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Bit.Core.Billing.Licenses;
|
||||
|
||||
public static class Registrations
|
||||
{
|
||||
public static void AddLicenseOperations(this IServiceCollection services)
|
||||
{
|
||||
// Queries
|
||||
services.AddTransient<IGetUserLicenseQuery, GetUserLicenseQuery>();
|
||||
}
|
||||
}
|
||||
@@ -228,6 +228,7 @@ public static class FeatureFlagKeys
|
||||
public const string CxpExportMobile = "cxp-export-mobile";
|
||||
|
||||
/* Platform Team */
|
||||
public const string WebPush = "web-push";
|
||||
public const string IpcChannelFramework = "ipc-channel-framework";
|
||||
public const string PushNotificationsWhenLocked = "pm-19388-push-notifications-when-locked";
|
||||
public const string PushNotificationsWhenInactive = "pm-25130-receive-push-notifications-for-inactive-users";
|
||||
@@ -244,7 +245,6 @@ public static class FeatureFlagKeys
|
||||
public const string CipherKeyEncryption = "cipher-key-encryption";
|
||||
public const string PM19941MigrateCipherDomainToSdk = "pm-19941-migrate-cipher-domain-to-sdk";
|
||||
public const string PhishingDetection = "phishing-detection";
|
||||
public const string RemoveCardItemTypePolicy = "pm-16442-remove-card-item-type-policy";
|
||||
public const string PM22134SdkCipherListView = "pm-22134-sdk-cipher-list-view";
|
||||
public const string PM22136_SdkCipherEncryption = "pm-22136-sdk-cipher-encryption";
|
||||
public const string PM23904_RiskInsightsForPremium = "pm-23904-risk-insights-for-premium";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Entities;
|
||||
namespace Bit.Core.Dirt.Entities;
|
||||
|
||||
public class OrganizationIntegration : ITableObject<Guid>
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Entities;
|
||||
namespace Bit.Core.Dirt.Entities;
|
||||
|
||||
public class OrganizationIntegrationConfiguration : ITableObject<Guid>
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.Enums;
|
||||
namespace Bit.Core.Dirt.Enums;
|
||||
|
||||
public enum IntegrationType : int
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
namespace Bit.Core.Dirt.Enums;
|
||||
|
||||
public enum OrganizationIntegrationStatus : int
|
||||
{
|
||||
@@ -1,13 +1,15 @@
|
||||
using Azure.Messaging.ServiceBus;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
using Bit.Core.AdminConsole.Models.Teams;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.AdminConsole.Services;
|
||||
using Bit.Core.AdminConsole.Services.NoopImplementations;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
using Bit.Core.Dirt.Models.Data.Teams;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Dirt.Services;
|
||||
using Bit.Core.Dirt.Services.Implementations;
|
||||
using Bit.Core.Dirt.Services.NoopImplementations;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
@@ -1,13 +1,13 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.AdminConsole.Services;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Dirt.Services;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
|
||||
/// <summary>
|
||||
/// Command implementation for creating organization integration configurations with validation and cache invalidation support.
|
||||
@@ -1,11 +1,11 @@
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
|
||||
/// <summary>
|
||||
/// Command implementation for deleting organization integration configurations with cache invalidation support.
|
||||
@@ -1,9 +1,9 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
|
||||
/// <summary>
|
||||
/// Query implementation for retrieving organization integration configurations.
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Command interface for creating organization integration configurations.
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Command interface for deleting organization integration configurations.
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Query interface for retrieving organization integration configurations.
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Command interface for updating organization integration configurations.
|
||||
@@ -1,13 +1,13 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.AdminConsole.Services;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations.Interfaces;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Dirt.Services;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrationConfigurations;
|
||||
|
||||
/// <summary>
|
||||
/// Command implementation for updating organization integration configurations with validation and cache invalidation support.
|
||||
@@ -1,12 +1,12 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations;
|
||||
|
||||
/// <summary>
|
||||
/// Command implementation for creating organization integrations with cache invalidation support.
|
||||
@@ -1,11 +1,11 @@
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations;
|
||||
|
||||
/// <summary>
|
||||
/// Command implementation for deleting organization integrations with cache invalidation support.
|
||||
@@ -1,8 +1,8 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations;
|
||||
|
||||
/// <summary>
|
||||
/// Query implementation for retrieving organization integrations.
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Command interface for creating an OrganizationIntegration.
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Command interface for deleting organization integrations.
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Query interface for retrieving organization integrations.
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Command interface for updating organization integrations.
|
||||
@@ -1,12 +1,12 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
using Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations.Interfaces;
|
||||
using Bit.Core.Dirt.Repositories;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace Bit.Core.AdminConsole.EventIntegrations.OrganizationIntegrations;
|
||||
namespace Bit.Core.Dirt.EventIntegrations.OrganizationIntegrations;
|
||||
|
||||
/// <summary>
|
||||
/// Command implementation for updating organization integrations with cache invalidation support.
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record DatadogIntegration(string ApiKey, Uri Uri);
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record DatadogIntegrationConfigurationDetails(string ApiKey, Uri Uri);
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class DatadogListenerConfiguration(GlobalSettings globalSettings)
|
||||
: ListenerConfiguration(globalSettings), IIntegrationListenerConfiguration
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record HecIntegration(Uri Uri, string Scheme, string Token, string? Service = null);
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class HecListenerConfiguration(GlobalSettings globalSettings)
|
||||
: ListenerConfiguration(globalSettings), IIntegrationListenerConfiguration
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public interface IEventListenerConfiguration
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public interface IIntegrationListenerConfiguration : IEventListenerConfiguration
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public interface IIntegrationMessage
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
/// <summary>
|
||||
/// Categories of event integration failures used for classification and retry logic.
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class IntegrationFilterGroup
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public enum IntegrationFilterOperation
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class IntegrationFilterRule
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of an integration handler operation, including success status,
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class IntegrationMessage : IIntegrationMessage
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Dirt.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class IntegrationOAuthState
|
||||
{
|
||||
@@ -4,7 +4,7 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class IntegrationTemplateContext(EventMessage eventMessage)
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public abstract class ListenerConfiguration
|
||||
{
|
||||
@@ -1,9 +1,8 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Models.Data.Organizations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class OrganizationIntegrationConfigurationDetails
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class RepositoryListenerConfiguration(GlobalSettings globalSettings)
|
||||
: ListenerConfiguration(globalSettings), IEventListenerConfiguration
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record SlackIntegration(string Token);
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record SlackIntegrationConfiguration(string ChannelId);
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record SlackIntegrationConfigurationDetails(string ChannelId, string Token);
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class SlackListenerConfiguration(GlobalSettings globalSettings) :
|
||||
ListenerConfiguration(globalSettings), IIntegrationListenerConfiguration
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.Models.Teams;
|
||||
using Bit.Core.Dirt.Models.Data.Teams;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record TeamsIntegration(
|
||||
string TenantId,
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record TeamsIntegrationConfigurationDetails(string ChannelId, Uri ServiceUrl);
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class TeamsListenerConfiguration(GlobalSettings globalSettings) :
|
||||
ListenerConfiguration(globalSettings), IIntegrationListenerConfiguration
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record WebhookIntegration(Uri Uri, string? Scheme = null, string? Token = null);
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record WebhookIntegrationConfiguration(Uri Uri, string? Scheme = null, string? Token = null);
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public record WebhookIntegrationConfigurationDetails(Uri Uri, string? Scheme = null, string? Token = null);
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Dirt.Enums;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
namespace Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
namespace Bit.Core.Dirt.Models.Data.EventIntegrations;
|
||||
|
||||
public class WebhookListenerConfiguration(GlobalSettings globalSettings)
|
||||
: ListenerConfiguration(globalSettings), IIntegrationListenerConfiguration
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Bit.Core.Models.Slack;
|
||||
namespace Bit.Core.Dirt.Models.Data.Slack;
|
||||
|
||||
public abstract class SlackApiResponse
|
||||
{
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user