Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PM-13446] Add 'IsMultiOrgEnterprise' column to 'Provider' table #4903

Conversation

jonashendrickx
Copy link
Member

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-13446

📔 Objective

Add an IsMultiOrgEnterprise column to the Provider table that will be used to differentiate between standard MSP’s and those who are multi-organization enterprises.

📸 Screenshots

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

Copy link

codecov bot commented Oct 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 41.74%. Comparing base (7a509d2) to head (311ec0a).
Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4903   +/-   ##
=======================================
  Coverage   41.74%   41.74%           
=======================================
  Files        1362     1362           
  Lines       63908    63909    +1     
  Branches     5857     5857           
=======================================
+ Hits        26678    26679    +1     
  Misses      36024    36024           
  Partials     1206     1206           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@amorask-bitwarden amorask-bitwarden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few things with your migration files.

@@ -0,0 +1,175 @@
-- Table
IF OBJECT_ID('[dbo].[ClientOrganizationMigrationRecord]') IS NULL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ It looks like you might have forgot to update the SQL Server migration script. This is just creating an unrelated table that already exists. Yours will look more like this, but just with the new IsMultiOrgEnterprise column.

namespace Bit.PostgresMigrations.Migrations;

/// <inheritdoc />
public partial class AddIsMultiOrgEnterpriseColumn : Migration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Looks like something got messed up with your EF Migration here. It appears to be rebuilding the entire database in this file. Check out your MySql migration file. That's what we want.

namespace Bit.SqliteMigrations.Migrations;

/// <inheritdoc />
public partial class AddIsMultiOrgEnterpriseColumn : Migration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Same thing here as with Postgres.

Copy link
Contributor

github-actions bot commented Oct 16, 2024

Logo
Checkmarx One – Scan Summary & Details695a78b1-dfa7-45a3-8a30-b40c27d23c2e

New Issues

Severity Issue Source File / Package Checkmarx Insight
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Missing User Instruction /Dockerfile: 1 A user should be specified in the dockerfile, otherwise the image will run as root
HIGH Passwords And Secrets - Generic Password /test-database.yml: 185 Query to find passwords and secrets in infrastructure code.
HIGH Passwords And Secrets - Generic Password /test-database.yml: 80 Query to find passwords and secrets in infrastructure code.
HIGH Passwords And Secrets - Generic Password /test-database.yml: 182 Query to find passwords and secrets in infrastructure code.
HIGH Passwords And Secrets - Generic Password /test-database.yml: 189 Query to find passwords and secrets in infrastructure code.
HIGH Passwords And Secrets - Generic Password /test-database.yml: 69 Query to find passwords and secrets in infrastructure code.
HIGH Passwords And Secrets - Generic Password /test-database.yml: 92 Query to find passwords and secrets in infrastructure code.
HIGH Passwords And Secrets - Generic Password /test-database.yml: 111 Query to find passwords and secrets in infrastructure code.
HIGH Passwords And Secrets - Generic Password /test-database.yml: 105 Query to find passwords and secrets in infrastructure code.
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile-k8s: 8 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile-k8s: 8 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 1 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 1 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 7 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 7 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 5 When installing a package, its pin version should be defined
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile: 1 When installing a package, its pin version should be defined
MEDIUM Image Version Using 'latest' /Dockerfile: 1 When building images, always tag them with useful tags which codify version information, intended destination (prod or test, for instance), stabili...
MEDIUM Unpinned Actions Full Length Commit SHA /_move_finalization_db_scripts.yml: 103 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /repository-management.yml: 111 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /cleanup-rc-branch.yml: 21 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /repository-management.yml: 119 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /release.yml: 44 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /build.yml: 548 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /build.yml: 582 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /repository-management.yml: 104 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /build.yml: 631 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /build.yml: 207 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /repository-management.yml: 60 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /_move_finalization_db_scripts.yml: 27 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /build.yml: 515 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
MEDIUM Unpinned Actions Full Length Commit SHA /release.yml: 63 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
LOW Healthcheck Instruction Missing /Dockerfile: 1 Ensure that HEALTHCHECK is being used. The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working
LOW Healthcheck Instruction Missing /Dockerfile: 1 Ensure that HEALTHCHECK is being used. The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working
LOW Healthcheck Instruction Missing /Dockerfile: 1 Ensure that HEALTHCHECK is being used. The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working
LOW Multiple RUN, ADD, COPY, Instructions Listed /Dockerfile-k8s: 17 Multiple commands (RUN, COPY, ADD) should be grouped in order to reduce the number of layers.
LOW Multiple RUN, ADD, COPY, Instructions Listed /Dockerfile: 13 Multiple commands (RUN, COPY, ADD) should be grouped in order to reduce the number of layers.
LOW Multiple RUN, ADD, COPY, Instructions Listed /Dockerfile: 11 Multiple commands (RUN, COPY, ADD) should be grouped in order to reduce the number of layers.
LOW Unpinned Actions Full Length Commit SHA /build.yml: 548 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
LOW Unpinned Actions Full Length Commit SHA /build.yml: 582 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
LOW Unpinned Actions Full Length Commit SHA /repository-management.yml: 60 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
LOW Unpinned Actions Full Length Commit SHA /repository-management.yml: 119 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
LOW Unpinned Actions Full Length Commit SHA /repository-management.yml: 104 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
LOW Unpinned Actions Full Length Commit SHA /repository-management.yml: 111 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
LOW Unpinned Actions Full Length Commit SHA /build.yml: 631 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...
LOW Unpinned Actions Full Length Commit SHA /build.yml: 515 Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps...

Fixed Issues

Severity Issue Source File / Package
MEDIUM CSRF /src/Admin/AdminConsole/Controllers/OrganizationsController.cs: 351
MEDIUM CSRF /src/Admin/AdminConsole/Controllers/OrganizationsController.cs: 351

Copy link
Member

@eliykat eliykat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a perfect case for adding a new ProviderType enum. Is there a reason we can't use that, or a particular need for adding a new column instead?

@amorask-bitwarden
Copy link
Contributor

This seems like a perfect case for adding a new ProviderType enum. Is there a reason we can't use that, or a particular need for adding a new column instead?

Hey @eliykat, we primarily decided against this because Multi-Enterprise Organizations are a subset of MSPs. Their functionality will be almost exactly the same as MSPs, but they will have different plan options during setup in the Bitwarden Portal. As such, it was my estimation that they don't actually represent a new provider type functionality-wise, but just an MSP that needs an indicator for a marginal functionality difference. This also allows us to re-use all of the existing Consolidated Billing functionality without having to add a new Enum check throughout the platform.

@eliykat
Copy link
Member

eliykat commented Oct 17, 2024

I think I have two main concerns about this:

  1. MSP has a semantic meaning in this domain: it's a managed service provider business. That is just a different thing than a single enterprise with multiple Bitwarden organizations. Calling a multi-org provider something it's not (an MSP) and then relying on a different property to define what it actually is, is confusing and a likely source of tech debt and bugs in the future. (See also - the Provider Information page in the Bitwarden Portal describes it as a type - I think the code should reflect the domain more closely.)
  2. This design allows invalid combinations: you could have a Reseller provider type with IsMultiOrgEnterprise enabled, which (from what I can tell) would be an invalid combination. If another provider type is added in the future, is it a new ProviderType enum or another bool column? Either allows additional invalid combinations which shouldn't be possible just as a matter of data / schema design. This is exactly why we added ProviderType previously.

I admit I am not familiar with the consolidated billing code, but being able to have a simple enum check seems better to me than enum && bool, or an implicit assumption that "MSP includes multi-org enterprises unless stated otherwise".

@amorask-bitwarden
Copy link
Contributor

I think I have two main concerns about this:

  1. MSP has a semantic meaning in this domain: it's a managed service provider business. That is just a different thing than a single enterprise with multiple Bitwarden organizations. Calling a multi-org provider something it's not (an MSP) and then relying on a different property to define what it actually is, is confusing and a likely source of tech debt and bugs in the future. (See also - the Provider Information page in the Bitwarden Portal describes it as a type - I think the code should reflect the domain more closely.)

  2. This design allows invalid combinations: you could have a Reseller provider type with IsMultiOrgEnterprise enabled, which (from what I can tell) would be an invalid combination. If another provider type is added in the future, is it a new ProviderType enum or another bool column? Either allows additional invalid combinations which shouldn't be possible just as a matter of data / schema design. This is exactly why we added ProviderType previously.

I admit I am not familiar with the consolidated billing code, but being able to have a simple enum check seems better to me than enum && bool, or an implicit assumption that "MSP includes multi-org enterprises unless stated otherwise".

Understood, that seems valid and reasonable. We'll adjust the approach here accordingly. @jonashendrickx hold off on additional work here as we'll close this ticket and re-work the next one as the starting point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants