1
0
mirror of https://github.com/bitwarden/server.git synced 2025-03-09 12:59:09 +01:00

[PM-15128] Add Promote Provider Service User functionality to Bitwarden Portal (#5118)

* Add Promote Provider Service User feature to Admin Portal

* Rename feature flag key for Promote Provider Service User tool
This commit is contained in:
Rui Tomé 2024-12-11 11:09:12 +00:00 committed by GitHub
parent 674e522843
commit 9b478107b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 98 additions and 1 deletions

View File

@ -3,7 +3,9 @@ using System.Text.Json;
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;
@ -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;
@ -41,6 +44,7 @@ public class ToolsController : Controller
ITransactionRepository transactionRepository,
IInstallationRepository installationRepository,
IOrganizationUserRepository organizationUserRepository,
IProviderUserRepository providerUserRepository,
ITaxRateRepository taxRateRepository,
IPaymentService paymentService,
IStripeAdapter stripeAdapter,
@ -53,6 +57,7 @@ public class ToolsController : Controller
_transactionRepository = transactionRepository;
_installationRepository = installationRepository;
_organizationUserRepository = organizationUserRepository;
_providerUserRepository = providerUserRepository;
_taxRateRepository = taxRateRepository;
_paymentService = paymentService;
_stripeAdapter = stripeAdapter;
@ -220,6 +225,46 @@ public class ToolsController : Controller
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()
{

View File

@ -44,6 +44,7 @@ public enum Permission
Tools_ChargeBrainTreeCustomer,
Tools_PromoteAdmin,
Tools_PromoteProviderServiceUser,
Tools_GenerateLicenseFile,
Tools_ManageTaxRates,
Tools_ManageStripeSubscriptions,

View File

@ -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; }
}

View File

@ -45,6 +45,7 @@ public static class RolePermissionMapping
Permission.Provider_ResendEmailInvite,
Permission.Tools_ChargeBrainTreeCustomer,
Permission.Tools_PromoteAdmin,
Permission.Tools_PromoteProviderServiceUser,
Permission.Tools_GenerateLicenseFile,
Permission.Tools_ManageTaxRates,
Permission.Tools_ManageStripeSubscriptions
@ -91,6 +92,7 @@ public static class RolePermissionMapping
Permission.Provider_ResendEmailInvite,
Permission.Tools_ChargeBrainTreeCustomer,
Permission.Tools_PromoteAdmin,
Permission.Tools_PromoteProviderServiceUser,
Permission.Tools_GenerateLicenseFile,
Permission.Tools_ManageTaxRates,
Permission.Tools_ManageStripeSubscriptions,

View File

@ -1,8 +1,10 @@
@using Bit.Admin.Enums;
@using Bit.Core
@inject SignInManager<IdentityUser> SignInManager
@inject Bit.Core.Settings.GlobalSettings GlobalSettings
@inject Bit.Admin.Services.IAccessControlService AccessControlService
@inject Bit.Core.Services.IFeatureService FeatureService
@{
var canViewUsers = AccessControlService.UserHasPermission(Permission.User_List_View);
@ -11,13 +13,15 @@
var canChargeBraintree = AccessControlService.UserHasPermission(Permission.Tools_ChargeBrainTreeCustomer);
var canCreateTransaction = AccessControlService.UserHasPermission(Permission.Tools_CreateEditTransaction);
var canPromoteAdmin = AccessControlService.UserHasPermission(Permission.Tools_PromoteAdmin);
var canPromoteProviderServiceUser = FeatureService.IsEnabled(FeatureFlagKeys.PromoteProviderServiceUserTool) &&
AccessControlService.UserHasPermission(Permission.Tools_PromoteProviderServiceUser);
var canGenerateLicense = AccessControlService.UserHasPermission(Permission.Tools_GenerateLicenseFile);
var canManageTaxRates = AccessControlService.UserHasPermission(Permission.Tools_ManageTaxRates);
var canManageStripeSubscriptions = AccessControlService.UserHasPermission(Permission.Tools_ManageStripeSubscriptions);
var canProcessStripeEvents = AccessControlService.UserHasPermission(Permission.Tools_ProcessStripeEvents);
var canMigrateProviders = AccessControlService.UserHasPermission(Permission.Tools_MigrateProviders);
var canViewTools = canChargeBraintree || canCreateTransaction || canPromoteAdmin ||
var canViewTools = canChargeBraintree || canCreateTransaction || canPromoteAdmin || canPromoteProviderServiceUser ||
canGenerateLicense || canManageTaxRates || canManageStripeSubscriptions;
}
@ -91,6 +95,12 @@
Promote Admin
</a>
}
@if (canPromoteProviderServiceUser)
{
<a class="dropdown-item" asp-controller="Tools" asp-action="PromoteProviderServiceUser">
Promote Provider Service User
</a>
}
@if (canGenerateLicense)
{
<a class="dropdown-item" asp-controller="Tools" asp-action="GenerateLicense">

View File

@ -0,0 +1,25 @@
@model PromoteProviderServiceUserModel
@{
ViewData["Title"] = "Promote Provider Service User";
}
<h1>Promote Provider Service User</h1>
<form method="post">
<div asp-validation-summary="All" class="alert alert-danger"></div>
<div class="row">
<div class="col-md">
<div class="mb-3">
<label asp-for="UserId" class="form-label"></label>
<input type="text" class="form-control" asp-for="UserId">
</div>
</div>
<div class="col-md">
<div class="mb-3">
<label asp-for="ProviderId" class="form-label"></label>
<input type="text" class="form-control" asp-for="ProviderId">
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">Promote Service User</button>
</form>

View File

@ -159,6 +159,7 @@ public static class FeatureFlagKeys
public const string InlineMenuTotp = "inline-menu-totp";
public const string PM12443RemovePagingLogic = "pm-12443-remove-paging-logic";
public const string SelfHostLicenseRefactor = "pm-11516-self-host-license-refactor";
public const string PromoteProviderServiceUserTool = "pm-15128-promote-provider-service-user-tool";
public static List<string> GetAllKeys()
{