Skip to content

Commit

Permalink
Merge branch 'main' into km/pm-13362/private-key-regen-endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas-Avery committed Dec 11, 2024
2 parents e38fb90 + 2d891b3 commit 22f326d
Show file tree
Hide file tree
Showing 200 changed files with 24,523 additions and 2,587 deletions.
5 changes: 5 additions & 0 deletions .devcontainer/internal_dev/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@
}
},
"postCreateCommand": "bash .devcontainer/internal_dev/postCreateCommand.sh",
"forwardPorts": [1080, 1433],
"portsAttributes": {
"1080": {
"label": "Mail Catcher",
"onAutoForward": "notify"
},
"1433": {
"label": "SQL Server",
"onAutoForward": "notify"
}
}
}
16 changes: 16 additions & 0 deletions .devcontainer/internal_dev/postCreateCommand.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,22 @@ Press <Enter> to continue."
sleep 5 # wait for DB container to start
dotnet run --project ./util/MsSqlMigratorUtility "$SQL_CONNECTION_STRING"
fi
read -r -p "Would you like to install the Stripe CLI? [y/N] " stripe_response
if [[ "$stripe_response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
install_stripe_cli
fi
}

# Install Stripe CLI
install_stripe_cli() {
echo "Installing Stripe CLI..."
# Add Stripe CLI GPG key so that apt can verify the packages authenticity.
# If Stripe ever changes the key, we'll need to update this. Visit https://docs.stripe.com/stripe-cli?install-method=apt if so
curl -s https://packages.stripe.dev/api/security/keypair/stripe-cli-gpg/public | gpg --dearmor | sudo tee /usr/share/keyrings/stripe.gpg >/dev/null
# Add Stripe CLI repository to apt sources
echo "deb [signed-by=/usr/share/keyrings/stripe.gpg] https://packages.stripe.dev/stripe-cli-debian-local stable main" | sudo tee -a /etc/apt/sources.list.d/stripe.list >/dev/null
sudo apt update
sudo apt install -y stripe
}

# main
Expand Down
13 changes: 8 additions & 5 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@

## These are shared workflows ##
.github/workflows/_move_finalization_db_scripts.yml
.github/workflows/build.yml
.github/workflows/cleanup-after-pr.yml
.github/workflows/cleanup-rc-branch.yml
.github/workflows/release.yml
.github/workflows/repository-management.yml

# Database Operations for database changes
src/Sql/** @bitwarden/dept-dbops
Expand All @@ -38,7 +34,6 @@ src/Identity @bitwarden/team-auth-dev
# Key Management team
**/KeyManagement @bitwarden/team-key-management-dev

**/SecretsManager @bitwarden/team-secrets-manager-dev
**/Tools @bitwarden/team-tools-dev

# Vault team
Expand Down Expand Up @@ -69,6 +64,14 @@ src/EventsProcessor @bitwarden/team-admin-console-dev
src/Admin/Controllers/ToolsController.cs @bitwarden/team-billing-dev
src/Admin/Views/Tools @bitwarden/team-billing-dev

# Platform team
.github/workflows/build.yml @bitwarden/team-platform-dev
.github/workflows/cleanup-after-pr.yml @bitwarden/team-platform-dev
.github/workflows/cleanup-rc-branch.yml @bitwarden/team-platform-dev
.github/workflows/repository-management.yml @bitwarden/team-platform-dev
.github/workflows/test-database.yml @bitwarden/team-platform-dev
.github/workflows/test.yml @bitwarden/team-platform-dev

# Multiple owners - DO NOT REMOVE (BRE)
**/packages.lock.json
Directory.Build.props
6 changes: 3 additions & 3 deletions .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
{
"matchManagers": ["github-actions", "dockerfile", "docker-compose"],
"commitMessagePrefix": "[deps] DevOps:"
"commitMessagePrefix": "[deps] BRE:"
},
{
"matchPackageNames": ["DnsClient"],
Expand Down Expand Up @@ -116,8 +116,8 @@
{
"matchPackageNames": ["CommandDotNet", "YamlDotNet"],
"description": "DevOps owned dependencies",
"commitMessagePrefix": "[deps] DevOps:",
"reviewers": ["team:dept-devops"]
"commitMessagePrefix": "[deps] BRE:",
"reviewers": ["team:dept-bre"]
},
{
"matchPackageNames": [
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,9 @@ jobs:

self-host-build:
name: Trigger self-host build
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
if: |
github.event_name != 'pull_request_target'
&& (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc')
runs-on: ubuntu-22.04
needs:
- build-docker
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>

<Version>2024.11.0</Version>
<Version>2024.12.1</Version>

<RootNamespace>Bit.$(MSBuildProjectName)</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ namespace Bit.Commercial.Core.AdminConsole.Services;

public class ProviderService : IProviderService
{
public static PlanType[] ProviderDisallowedOrganizationTypes = new[] { PlanType.Free, PlanType.FamiliesAnnually, PlanType.FamiliesAnnually2019 };
private static readonly PlanType[] _resellerDisallowedOrganizationTypes = [
PlanType.Free,
PlanType.FamiliesAnnually,
PlanType.FamiliesAnnually2019
];

private readonly IDataProtector _dataProtector;
private readonly IMailService _mailService;
Expand Down Expand Up @@ -690,13 +694,14 @@ private void ThrowOnInvalidPlanType(ProviderType providerType, PlanType requeste
throw new BadRequestException($"Multi-organization Enterprise Providers cannot manage organizations with the plan type {requestedType}. Only Enterprise (Monthly) and Enterprise (Annually) are allowed.");
}
break;
case ProviderType.Reseller:
if (_resellerDisallowedOrganizationTypes.Contains(requestedType))
{
throw new BadRequestException($"Providers cannot manage organizations with the requested plan type ({requestedType}). Only Teams and Enterprise accounts are allowed.");
}
break;
default:
throw new BadRequestException($"Unsupported provider type {providerType}.");
}

if (ProviderDisallowedOrganizationTypes.Contains(requestedType))
{
throw new BadRequestException($"Providers cannot manage organizations with the requested plan type ({requestedType}). Only Teams and Enterprise accounts are allowed.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ private void UpdateOrganization(Organization organization, OrganizationEditModel
organization.UseTotp = model.UseTotp;
organization.UsersGetPremium = model.UsersGetPremium;
organization.UseSecretsManager = model.UseSecretsManager;
organization.UseRiskInsights = model.UseRiskInsights;

//secrets
organization.SmSeats = model.SmSeats;
Expand Down
6 changes: 5 additions & 1 deletion src/Admin/AdminConsole/Models/OrganizationEditModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public OrganizationEditModel(
Use2fa = org.Use2fa;
UseApi = org.UseApi;
UseSecretsManager = org.UseSecretsManager;
UseRiskInsights = org.UseRiskInsights;
UseResetPassword = org.UseResetPassword;
SelfHost = org.SelfHost;
UsersGetPremium = org.UsersGetPremium;
Expand Down Expand Up @@ -143,7 +144,9 @@ public OrganizationEditModel(
[Display(Name = "SCIM")]
public bool UseScim { get; set; }
[Display(Name = "Secrets Manager")]
public bool UseSecretsManager { get; set; }
public new bool UseSecretsManager { get; set; }
[Display(Name = "Risk Insights")]
public new bool UseRiskInsights { get; set; }
[Display(Name = "Self Host")]
public bool SelfHost { get; set; }
[Display(Name = "Users Get Premium")]
Expand Down Expand Up @@ -284,6 +287,7 @@ public Organization ToOrganization(Organization existingOrganization)
existingOrganization.Use2fa = Use2fa;
existingOrganization.UseApi = UseApi;
existingOrganization.UseSecretsManager = UseSecretsManager;
existingOrganization.UseRiskInsights = UseRiskInsights;
existingOrganization.UseResetPassword = UseResetPassword;
existingOrganization.SelfHost = SelfHost;
existingOrganization.UsersGetPremium = UsersGetPremium;
Expand Down
1 change: 1 addition & 0 deletions src/Admin/AdminConsole/Models/OrganizationViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ public OrganizationViewModel(Organization org, Provider provider, IEnumerable<Or
public int ServiceAccountsCount { get; set; }
public int OccupiedSmSeatsCount { get; set; }
public bool UseSecretsManager => Organization.UseSecretsManager;
public bool UseRiskInsights => Organization.UseRiskInsights;
}
18 changes: 5 additions & 13 deletions src/Admin/AdminConsole/Views/Organizations/_ViewInformation.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,11 @@
<dt class="col-sm-4 col-lg-3">Administrators manage all collections</dt>
<dd id="pm-manage-collections" class="col-sm-8 col-lg-9">@(Model.Organization.AllowAdminAccessToAllCollectionItems ? "On" : "Off")</dd>

@if (!FeatureService.IsEnabled(Bit.Core.FeatureFlagKeys.LimitCollectionCreationDeletionSplit))
{
<dt class="col-sm-4 col-lg-3">Limit collection creation to administrators</dt>
<dd id="pm-collection-creation" class="col-sm-8 col-lg-9">@(Model.Organization.LimitCollectionCreationDeletion ? "On" : "Off")</dd>
}
else
{
<dt class="col-sm-4 col-lg-3">Limit collection creation to administrators</dt>
<dd id="pm-collection-creation" class="col-sm-8 col-lg-9">@(Model.Organization.LimitCollectionCreation ? "On" : "Off")</dd>

<dt class="col-sm-4 col-lg-3">Limit collection deletion to administrators</dt>
<dd id="pm-collection-deletion" class="col-sm-8 col-lg-9">@(Model.Organization.LimitCollectionDeletion ? "On" : "Off")</dd>
}
<dt class="col-sm-4 col-lg-3">Limit collection creation to administrators</dt>
<dd id="pm-collection-creation" class="col-sm-8 col-lg-9">@(Model.Organization.LimitCollectionCreation ? "On" : "Off")</dd>

<dt class="col-sm-4 col-lg-3">Limit collection deletion to administrators</dt>
<dd id="pm-collection-deletion" class="col-sm-8 col-lg-9">@(Model.Organization.LimitCollectionDeletion ? "On" : "Off")</dd>
</dl>

<h2>Secrets Manager</h2>
Expand Down
13 changes: 10 additions & 3 deletions src/Admin/AdminConsole/Views/Shared/_OrganizationForm.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
</div>
</div>
<h2>Features</h2>
<div class="row mb-3">
<div class="row mb-4">
<div class="col-4">
<h3>General</h3>
<div class="form-check mb-2">
Expand Down Expand Up @@ -146,7 +146,7 @@
<label class="form-check-label" asp-for="UseCustomPermissions"></label>
</div>
</div>
<div class="col-4">
<div class="col-3">
<h3>Password Manager</h3>
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="UseTotp" disabled='@(canEditPlan ? null : "disabled")'>
Expand All @@ -157,13 +157,20 @@
<label class="form-check-label" asp-for="UsersGetPremium"></label>
</div>
</div>
<div class="col-4">
<div class="col-3">
<h3>Secrets Manager</h3>
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="UseSecretsManager" disabled='@(canEditPlan ? null : "disabled")'>
<label class="form-check-label" asp-for="UseSecretsManager"></label>
</div>
</div>
<div class="col-2">
<h3>Access Insights</h3>
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="UseRiskInsights" disabled='@(canEditPlan ? null : "disabled")'>
<label class="form-check-label" asp-for="UseRiskInsights"></label>
</div>
</div>
</div>
}

Expand Down
45 changes: 45 additions & 0 deletions src/Admin/Controllers/ToolsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
using Bit.Admin.Enums;
using Bit.Admin.Models;
using Bit.Admin.Utilities;
using Bit.Core;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Entities;
using Bit.Core.Models.BitStripe;
using Bit.Core.OrganizationFeatures.OrganizationLicenses.Interfaces;
Expand All @@ -28,6 +30,7 @@ public class ToolsController : Controller
private readonly ITransactionRepository _transactionRepository;
private readonly IInstallationRepository _installationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IProviderUserRepository _providerUserRepository;
private readonly IPaymentService _paymentService;
private readonly ITaxRateRepository _taxRateRepository;
private readonly IStripeAdapter _stripeAdapter;
Expand All @@ -41,6 +44,7 @@ public ToolsController(
ITransactionRepository transactionRepository,
IInstallationRepository installationRepository,
IOrganizationUserRepository organizationUserRepository,
IProviderUserRepository providerUserRepository,
ITaxRateRepository taxRateRepository,
IPaymentService paymentService,
IStripeAdapter stripeAdapter,
Expand All @@ -53,6 +57,7 @@ public ToolsController(
_transactionRepository = transactionRepository;
_installationRepository = installationRepository;
_organizationUserRepository = organizationUserRepository;
_providerUserRepository = providerUserRepository;
_taxRateRepository = taxRateRepository;
_paymentService = paymentService;
_stripeAdapter = stripeAdapter;
Expand Down Expand Up @@ -220,6 +225,46 @@ public async Task<IActionResult> PromoteAdmin(PromoteAdminModel model)
return RedirectToAction("Edit", "Organizations", new { id = model.OrganizationId.Value });
}

[RequireFeature(FeatureFlagKeys.PromoteProviderServiceUserTool)]
[RequirePermission(Permission.Tools_PromoteProviderServiceUser)]
public IActionResult PromoteProviderServiceUser()
{
return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
[RequireFeature(FeatureFlagKeys.PromoteProviderServiceUserTool)]
[RequirePermission(Permission.Tools_PromoteProviderServiceUser)]
public async Task<IActionResult> PromoteProviderServiceUser(PromoteProviderServiceUserModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}

var providerUsers = await _providerUserRepository.GetManyByProviderAsync(
model.ProviderId.Value, null);
var serviceUser = providerUsers.FirstOrDefault(u => u.UserId == model.UserId.Value);
if (serviceUser == null)
{
ModelState.AddModelError(nameof(model.UserId), "Service User Id not found in this provider.");
}
else if (serviceUser.Type != Core.AdminConsole.Enums.Provider.ProviderUserType.ServiceUser)
{
ModelState.AddModelError(nameof(model.UserId), "User is not a service user of this provider.");
}

if (!ModelState.IsValid)
{
return View(model);
}

serviceUser.Type = Core.AdminConsole.Enums.Provider.ProviderUserType.ProviderAdmin;
await _providerUserRepository.ReplaceAsync(serviceUser);
return RedirectToAction("Edit", "Providers", new { id = model.ProviderId.Value });
}

[RequirePermission(Permission.Tools_GenerateLicenseFile)]
public IActionResult GenerateLicense()
{
Expand Down
1 change: 1 addition & 0 deletions src/Admin/Enums/Permissions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public enum Permission

Tools_ChargeBrainTreeCustomer,
Tools_PromoteAdmin,
Tools_PromoteProviderServiceUser,
Tools_GenerateLicenseFile,
Tools_ManageTaxRates,
Tools_ManageStripeSubscriptions,
Expand Down
13 changes: 13 additions & 0 deletions src/Admin/Models/PromoteProviderServiceUserModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;

namespace Bit.Admin.Models;

public class PromoteProviderServiceUserModel
{
[Required]
[Display(Name = "Provider Service User Id")]
public Guid? UserId { get; set; }
[Required]
[Display(Name = "Provider Id")]
public Guid? ProviderId { get; set; }
}
10 changes: 3 additions & 7 deletions src/Admin/Models/UserEditModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ namespace Bit.Admin.Models;

public class UserEditModel
{
public UserEditModel()
{

}
public UserEditModel() { }

public UserEditModel(
User user,
Expand All @@ -21,10 +18,9 @@ public UserEditModel(
BillingInfo billingInfo,
BillingHistoryInfo billingHistoryInfo,
GlobalSettings globalSettings,
bool? domainVerified
)
bool? claimedAccount)
{
User = UserViewModel.MapViewModel(user, isTwoFactorEnabled, ciphers, domainVerified);
User = UserViewModel.MapViewModel(user, isTwoFactorEnabled, ciphers, claimedAccount);

BillingInfo = billingInfo;
BillingHistoryInfo = billingHistoryInfo;
Expand Down
Loading

0 comments on commit 22f326d

Please sign in to comment.