Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 46 additions & 60 deletions util/Seeder/Seeds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,35 @@ Hand-crafted JSON fixtures for Bitwarden Seeder test data.

## Quick Start

1. Copy template from `templates/` to appropriate `fixtures/` subfolder
2. Edit JSON (your editor validates against `$schema` automatically)
1. Create a JSON file in the right `fixtures/` subfolder
2. Add the `$schema` line — your editor picks up validation automatically
3. Build to verify: `dotnet build util/Seeder/Seeder.csproj`

## File Structure
## Writing Fixtures

```
Seeds/
├── fixtures/ Your seed data goes here
│ ├── ciphers/ Vault items
│ ├── organizations/ Organization definitions
│ ├── rosters/ Users, groups, collections, permissions
│ └── presets/ Complete seeding scenarios
├── schemas/ JSON Schema validation (auto-checked by editors)
├── templates/ Starter files - copy these
└── README.md This file
```
### Organizations

Just a name and domain. That's it.
Domains must use `.example` (RFC 2606 — guaranteed unresolvable, safe for QA email pipelines).
Plan type and seats are defined in presets, not here.

See: `fixtures/organizations/redwood-analytics.json`

### Rosters

Users, groups, and collections for an org.

- Users have a `firstName`, `lastName`, and `role` (`owner`, `admin`, `user`, `custom`)
- The Seeder pipeline builds emails as `firstName.lastName@domain`, so `"Family"` + `"Mom"` at domain `acme.example` becomes `family.mom@acme.example` or `a1b2c3d4+family.mom@acme.example` with mangling on
- Groups reference users by that same email prefix (e.g. `"family.mom"`)
- Collections assign permissions to groups or individual users (`readOnly`, `hidePasswords`, `manage` — all default false)

## Fixtures Overview
See: `starter-team.json` (minimal), `family.json` (groups + collections), `dunder-mifflin.json` (58-user enterprise)

### Ciphers

Vault items. Each item needs a `type` and `name`.

| Type | Required Object | Description |
| ------------ | --------------- | -------------------------- |
| `login` | `login` | Website credentials + URIs |
Expand All @@ -34,77 +41,56 @@ Seeds/
| `secureNote` | — | Uses `notes` field only |
| `sshKey` | `sshKey` | SSH key credentials |

**Schema**: `schemas/cipher.schema.json`

### Organizations

Organization identity definitions with name and domain. Plan type and seats are defined in presets, not org fixtures.

**Required fields**: `name`, `domain`

**Schema**: `schemas/organization.schema.json`
See: `fixtures/ciphers/enterprise-basic.json`

### Rosters

Complete user/group/collection structures with permissions. User emails auto-generated as `firstName.lastName@domain`.
### Presets

**User roles**: `owner`, `admin`, `user`, `custom`
**Collection permissions**: `readOnly`, `hidePasswords`, `manage`
**Schema**: `schemas/roster.schema.json`
**Example**: See `fixtures/rosters/dunder-mifflin.json` for a complete 58-user example
Presets **wire everything together**: org + roster + ciphers. You can reference fixtures by name or generate data with counts.

### Presets
Three styles:

Combine organization, roster, and ciphers into complete scenarios. Presets can reference fixtures, generate data programmatically, or mix both approaches.
- **Fixture-based**: `enterprise-basic.json` — references org, roster, and cipher fixtures
- **Generated**: `wonka-teams-small.json` — uses `count` parameters to create users, groups, collections, ciphers
- **Feature-specific**: `tde-enterprise.json`, `policy-enterprise.json` — adds SSO config, policies

**Key features**:
Presets can also define inline orgs (name + domain right in the preset) instead of referencing a fixture — see `large-enterprise.json`.

- Reference existing fixtures by name
- Generate users, groups, collections, and ciphers with count parameters
- Add personal ciphers (user-owned, encrypted with user key, not in collections)
- Mix fixture references and generated data
## Naming Conventions

**Schema**: `schemas/preset.schema.json`
**Examples**: See `fixtures/presets/` for complete examples including fixture-based, generated, and hybrid approaches
| Element | Pattern | Example |
| ----------- | ------------------ | --------------------- |
| File names | kebab-case | `banking-logins.json` |
| Item names | Title case, unique | `Chase Bank Login` |
| User refs | firstName.lastName | `jane.doe` |
| Org domains | .example | `acme.example` |

## Validation

Modern editors validate against `$schema` automatically - errors appear as red squiggles.

Build errors catch schema violations:
Your editor validates against `$schema` automatically — errors show up as red squiggles. Build also catches schema violations:

```bash
dotnet build util/Seeder/Seeder.csproj
```

## Naming Conventions

| Element | Pattern | Example |
| ----------- | ------------------ | ------------------------ |
| File names | kebab-case | `banking-logins.json` |
| Item names | Title case, unique | `Chase Bank Login` |
| User refs | firstName.lastName | `jane.doe` |
| Org domains | Realistic or .test | `acme.com`, `test.local` |

## QA Test Fixture Migration Matrix

These Seeds consolidate test data previously found across the `bitwarden/test` repo.
The table below maps existing QA fixtures to their Seeder equivalents.

| QA Source (`test/Bitwarden.Web.Tests/TestData/SetupData/`) | Used By | Seeder Preset | Org Fixture | Roster Fixture | Cipher Fixture |
| ---------------------------------------------------------- | --------------------------------- | ----------------------------------- | --------------------------- | ------------------------ | ------------------------ |
| `CollectionPermissionsOrg.json` | Web, Extension | `collection-permissions-enterprise` | `qa-collection-permissions` | `collection-permissions` | `collection-permissions` |
| `EnterpriseOrg.json` | Web, Extension, Android, iOS, CLI | `enterprise-basic` | `qa-enterprise` | `enterprise-basic` | `enterprise-basic` |
| `SsoOrg.json` | Web | `sso-enterprise` | `qa-sso-org` | `sso-basic` | `sso-vault` |
| `TDEOrg.json` | Web, Extension, Android, iOS | `tde-enterprise` | `qa-tde-org` | `tde-basic` | `tde-vault` |
| _(Confluence: Policy Org guide)_ | QA manual setup | `policy-enterprise` | `qa-policy-org` | `policy-org` | — |
| QA Source (`test/Bitwarden.Web.Tests/TestData/SetupData/`) | Used By | Seeder Preset | Org Fixture | Roster Fixture | Cipher Fixture |
| ---------------------------------------------------------- | --------------------------------- | ----------------------------------- | ------------------- | ------------------------ | ------------------------ |
| `CollectionPermissionsOrg.json` | Web, Extension | `collection-permissions-enterprise` | `cobalt-logistics` | `collection-permissions` | `collection-permissions` |
| `EnterpriseOrg.json` | Web, Extension, Android, iOS, CLI | `enterprise-basic` | `redwood-analytics` | `enterprise-basic` | `enterprise-basic` |
| `SsoOrg.json` | Web | `sso-enterprise` | `verdant-health` | `starter-team` | `sso-vault` |
| `TDEOrg.json` | Web, Extension, Android, iOS | `tde-enterprise` | `obsidian-labs` | `starter-team` | `tde-vault` |
| _(Confluence: Policy Org guide)_ | QA manual setup | `policy-enterprise` | `pinnacle-designs` | `starter-team` | — |
| `FamiliesOrg.json` | Web, Extension | `families-basic` | `adams-family` | `family` | — |

### Not Yet Migrated

| QA Source | Used By | Status |
| --------------------- | ---------------------------- | --------------------------------------------------------------------- |
| `FreeAccount.json` | All 7 platforms | Planned — `free-personal-vault` preset (separate PR due to file size) |
| `FamiliesOrg.json` | Web, Extension | Planned — `families-basic` preset |
| `PremiumAccount.json` | Web, Extension, Android, iOS | Planned — `premium-personal-vault` preset |
| `SecretsManager.json` | Web | Planned — `secrets-manager-enterprise` preset |
| `FreeOrg.json` | Web | Planned — `free-org-basic` preset |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "TDE QA Org",
"domain": "qa-tde.test"
"name": "Adams Family",
"domain": "adams.example"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Cobalt Logistics",
"domain": "cobalt.example"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Dunder Mifflin",
"domain": "dundermifflin.com"
"domain": "dundermifflin.example"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Maple & Pine Trading Co",
"domain": "maplepine.com"
"domain": "maplepine.example"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "SSO QA Org",
"domain": "qa-sso.test"
"name": "Obsidian Labs",
"domain": "obsidian.example"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Pinnacle Designs",
"domain": "pinnacle.example"
}

This file was deleted.

5 changes: 0 additions & 5 deletions util/Seeder/Seeds/fixtures/organizations/qa-enterprise.json

This file was deleted.

5 changes: 0 additions & 5 deletions util/Seeder/Seeds/fixtures/organizations/qa-policy-org.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Redwood Analytics",
"domain": "redwood.example"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Stark Industries",
"domain": "stark.dev"
"domain": "stark.example"
}
5 changes: 5 additions & 0 deletions util/Seeder/Seeds/fixtures/organizations/verdant-health.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Verdant Health",
"domain": "verdant.example"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Wonka Confections",
"domain": "wonka.co"
"domain": "wonka.example"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "../../schemas/organization.schema.json",
"name": "Zero Knowledge Labs",
"domain": "zero-knowledge.example"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "../../schemas/preset.schema.json",
"organization": {
"fixture": "qa-collection-permissions",
"fixture": "cobalt-logistics",
"planType": "enterprise-annually",
"seats": 10
},
Expand Down
2 changes: 1 addition & 1 deletion util/Seeder/Seeds/fixtures/presets/enterprise-basic.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "../../schemas/preset.schema.json",
"organization": {
"fixture": "qa-enterprise",
"fixture": "redwood-analytics",
"planType": "enterprise-annually",
"seats": 10
},
Expand Down
19 changes: 19 additions & 0 deletions util/Seeder/Seeds/fixtures/presets/families-basic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "../../schemas/preset.schema.json",
"organization": {
"fixture": "adams-family",
"planType": "families-annually",
"seats": 6
},
"roster": {
"fixture": "family"
},
"folders": true,
"ciphers": {
"count": 150,
"assignFolders": true
},
"personalCiphers": {
"countPerUser": 65
}
}
2 changes: 1 addition & 1 deletion util/Seeder/Seeds/fixtures/presets/large-enterprise.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "../../schemas/preset.schema.json",
"organization": {
"name": "Globex Corp",
"domain": "globex.com",
"domain": "globex.example",
"seats": 10000
},
"users": {
Expand Down
4 changes: 2 additions & 2 deletions util/Seeder/Seeds/fixtures/presets/policy-enterprise.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"$schema": "../../schemas/preset.schema.json",
"organization": {
"fixture": "qa-policy-org",
"fixture": "pinnacle-designs",
"planType": "enterprise-annually"
},
"roster": {
"fixture": "policy-org"
"fixture": "starter-team"
},
"policies": {
"enableAll": true,
Expand Down
6 changes: 3 additions & 3 deletions util/Seeder/Seeds/fixtures/presets/sso-enterprise.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"$schema": "../../schemas/preset.schema.json",
"organization": {
"fixture": "qa-sso-org",
"fixture": "verdant-health",
"planType": "enterprise-annually",
"seats": 10
},
"roster": {
"fixture": "sso-basic"
"fixture": "starter-team"
},
"ciphers": {
"fixture": "sso-vault"
Expand All @@ -15,7 +15,7 @@
"enable": ["requireSso"]
},
"sso": {
"identifier": "qa-sso-org",
"identifier": "verdant-health",
"encryptionType": "masterPassword",
"provider": "oidc"
}
Expand Down
6 changes: 3 additions & 3 deletions util/Seeder/Seeds/fixtures/presets/tde-enterprise.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"$schema": "../../schemas/preset.schema.json",
"organization": {
"fixture": "qa-tde-org",
"fixture": "obsidian-labs",
"planType": "enterprise-annually",
"seats": 10
},
"roster": {
"fixture": "tde-basic"
"fixture": "starter-team"
},
"ciphers": {
"fixture": "tde-vault"
Expand All @@ -15,7 +15,7 @@
"enable": ["requireSso"]
},
"sso": {
"identifier": "qa-tde-org",
"identifier": "obsidian-labs",
"encryptionType": "trustedDevices",
"provider": "oidc"
}
Expand Down

This file was deleted.

Loading
Loading