diff --git a/src/Admin/Controllers/ProvidersController.cs b/src/Admin/Controllers/ProvidersController.cs index def79dbde7..e0826d7776 100644 --- a/src/Admin/Controllers/ProvidersController.cs +++ b/src/Admin/Controllers/ProvidersController.cs @@ -195,4 +195,24 @@ public class ProvidersController : Controller return RedirectToAction("Edit", "Providers", new { id = id }); } + + [HttpGet] + public async Task CreateOrganization(Guid providerId) + { + var provider = await _providerRepository.GetByIdAsync(providerId); + if (provider is not { Type: ProviderType.Reseller }) + { + return RedirectToAction("Index"); + } + + return View(new OrganizationEditModel(provider)); + } + + [HttpPost] + public async Task CreateOrganization(Guid providerId, OrganizationEditModel model) + { + // TODO : Insert logic to create the new Organization entry, create an OrganizationUser entry for the owner and send the invitation email + + return RedirectToAction("Edit", "Providers", new { id = providerId }); + } } diff --git a/src/Admin/Models/OrganizationEditModel.cs b/src/Admin/Models/OrganizationEditModel.cs index a8c9620bcf..cb44e1725c 100644 --- a/src/Admin/Models/OrganizationEditModel.cs +++ b/src/Admin/Models/OrganizationEditModel.cs @@ -2,11 +2,13 @@ using Bit.Core.Entities; using Bit.Core.Entities.Provider; using Bit.Core.Enums; +using Bit.Core.Enums.Provider; using Bit.Core.Models.Business; using Bit.Core.Models.Data.Organizations.OrganizationUsers; using Bit.Core.Settings; using Bit.Core.Utilities; using Bit.Core.Vault.Entities; +using Bit.SharedWeb.Utilities; namespace Bit.Admin.Models; @@ -14,6 +16,14 @@ public class OrganizationEditModel : OrganizationViewModel { public OrganizationEditModel() { } + public OrganizationEditModel(Provider provider) + { + Provider = provider; + BillingEmail = provider.Type == ProviderType.Reseller ? provider.BillingEmail : string.Empty; + PlanType = Core.Enums.PlanType.TeamsMonthly; + Plan = Core.Enums.PlanType.TeamsMonthly.GetDisplayAttribute()?.GetName(); + } + public OrganizationEditModel(Organization org, Provider provider, IEnumerable orgUsers, IEnumerable ciphers, IEnumerable collections, IEnumerable groups, IEnumerable policies, BillingInfo billingInfo, IEnumerable connections, @@ -25,7 +35,7 @@ public class OrganizationEditModel : OrganizationViewModel Name = org.Name; BusinessName = org.BusinessName; - BillingEmail = org.BillingEmail; + BillingEmail = provider?.Type == ProviderType.Reseller ? provider.BillingEmail : org.BillingEmail; PlanType = org.PlanType; Plan = org.Plan; Seats = org.Seats; diff --git a/src/Admin/Views/Organizations/Edit.cshtml b/src/Admin/Views/Organizations/Edit.cshtml index c4726ed362..d959f04a01 100644 --- a/src/Admin/Views/Organizations/Edit.cshtml +++ b/src/Admin/Views/Organizations/Edit.cshtml @@ -1,21 +1,20 @@ @model OrganizationEditModel @{ - ViewData["Title"] = "Organization: " + Model.Organization.Name; + ViewData["Title"] = (Model.Provider != null ? "Client " : string.Empty) + "Organization: " + Model.Organization.Name; } @section Scripts { + @await Html.PartialAsync("_OrganizationFormScripts") + } -

Organization @Model.Organization.Name

+

@(Model.Provider != null ? "Client " : string.Empty)Organization @Model.Organization.Name

@if (Model.Provider != null) { @@ -127,218 +84,7 @@

Billing Information

@await Html.PartialAsync("_BillingInformation", new BillingInformationModel { BillingInfo = Model.BillingInfo, OrganizationId = Model.Organization.Id }) -
- -

General

-
-
-
- - -
-
-
-
- - -
-

Business Information

-
-
-
- - -
-
-
-

Plan

-
-
-
- - -
-
-
-
- - -
-
-
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
-
-
- - -
-
-
-

Features

-
-
-

General

-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-

Password Manager

-
- - -
-
- - -
-
-
-

Secrets Manager

-
- - -
-
-
- -

Licensing

-
-
-
- - -
-
-
-
- - -
-
-
-

Billing

-
-
-
- - @if (Model.Provider?.Type == ProviderType.Reseller) - { - - } - else - { - - } -
-
-
-
-
- - -
-
-
-
-
-
-
- -
- -
- -
-
-
-
-
-
- -
- -
- -
-
-
-
-
-
+@await Html.PartialAsync("_OrganizationForm", Model)
diff --git a/src/Admin/Views/Providers/CreateOrganization.cshtml b/src/Admin/Views/Providers/CreateOrganization.cshtml new file mode 100644 index 0000000000..219b6854b9 --- /dev/null +++ b/src/Admin/Views/Providers/CreateOrganization.cshtml @@ -0,0 +1,21 @@ +@model OrganizationEditModel +@{ + ViewData["Title"] = "Create Client Organization"; +} + +@section Scripts { + @await Html.PartialAsync("_OrganizationFormScripts") +} + +

New Client Organization

+ +@await Html.PartialAsync("_OrganizationForm", Model) +
+ +
+
+ +
+
+
diff --git a/src/Admin/Views/Providers/Organizations.cshtml b/src/Admin/Views/Providers/Organizations.cshtml index ca376cbdfc..1c11c87ad2 100644 --- a/src/Admin/Views/Providers/Organizations.cshtml +++ b/src/Admin/Views/Providers/Organizations.cshtml @@ -12,7 +12,7 @@ @if (Model.Provider.Type == ProviderType.Reseller) { } diff --git a/src/Admin/Views/Shared/_OrganizationForm.cshtml b/src/Admin/Views/Shared/_OrganizationForm.cshtml new file mode 100644 index 0000000000..d76c45b7d1 --- /dev/null +++ b/src/Admin/Views/Shared/_OrganizationForm.cshtml @@ -0,0 +1,247 @@ +@using Bit.SharedWeb.Utilities +@model OrganizationEditModel + +
+ +

General

+
+
+
+ + +
+
+
+ + @if (Model.Provider?.Type == ProviderType.Reseller) + { +
+
+
+ + @if (!string.IsNullOrWhiteSpace(Model.Owners)) + { + + } + else + { + + } + +
+
+
+ } + @if (Model.Organization != null) + { +
+ + +
+ } +

Business Information

+
+
+
+ + +
+
+
+

Plan

+
+
+
+ + @{ + var planTypes = Enum.GetValues() + .Where(p => Model.Provider == null || p is >= PlanType.TeamsMonthly and <= PlanType.EnterpriseAnnually) + .Select(e => new SelectListItem + { + Value = ((int)e).ToString(), + Text = e.GetDisplayAttribute()?.GetName() ?? e.ToString() + }) + .ToList(); + } + +
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+

Features

+
+
+

General

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+

Password Manager

+
+ + +
+
+ + +
+
+
+

Secrets Manager

+
+ + +
+
+
+ +

Licensing

+
+
+
+ + +
+
+
+
+ + +
+
+
+

Billing

+
+
+
+ + @if (Model.Provider?.Type == ProviderType.Reseller) + { + + } + else + { + + } +
+
+
+
+
+ + +
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/src/Admin/Views/Shared/_OrganizationFormScripts.cshtml b/src/Admin/Views/Shared/_OrganizationFormScripts.cshtml new file mode 100644 index 0000000000..82d5deb12e --- /dev/null +++ b/src/Admin/Views/Shared/_OrganizationFormScripts.cshtml @@ -0,0 +1,35 @@ + \ No newline at end of file