mirror of
https://github.com/bitwarden/server.git
synced 2025-02-16 01:51:21 +01:00
Remove policies from the portal (#1534)
This commit is contained in:
parent
4bc683c38d
commit
69e7c651cd
@ -1,175 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Portal.Models;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bit.Portal.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
public class PoliciesController : Controller
|
||||
{
|
||||
private readonly IUserService _userService;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly EnterprisePortalCurrentContext _enterprisePortalCurrentContext;
|
||||
private readonly II18nService _i18nService;
|
||||
|
||||
public PoliciesController(
|
||||
IUserService userService,
|
||||
IOrganizationService organizationService,
|
||||
IPolicyService policyService,
|
||||
IPolicyRepository policyRepository,
|
||||
EnterprisePortalCurrentContext enterprisePortalCurrentContext,
|
||||
II18nService i18nService)
|
||||
{
|
||||
_userService = userService;
|
||||
_organizationService = organizationService;
|
||||
_policyService = policyService;
|
||||
_policyRepository = policyRepository;
|
||||
_enterprisePortalCurrentContext = enterprisePortalCurrentContext;
|
||||
_i18nService = i18nService;
|
||||
}
|
||||
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
var orgId = _enterprisePortalCurrentContext.SelectedOrganizationId;
|
||||
if (orgId == null)
|
||||
{
|
||||
return Redirect("~/");
|
||||
}
|
||||
|
||||
if (!_enterprisePortalCurrentContext.SelectedOrganizationDetails.UsePolicies ||
|
||||
!_enterprisePortalCurrentContext.CanManagePoliciesForSelectedOrganization)
|
||||
{
|
||||
return Redirect("~/");
|
||||
}
|
||||
|
||||
var policies = await _policyRepository.GetManyByOrganizationIdAsync(orgId.Value);
|
||||
return View(new PoliciesModel(policies, _enterprisePortalCurrentContext.SelectedOrganizationDetails));
|
||||
}
|
||||
|
||||
[HttpGet("/edit/{type}")]
|
||||
public async Task<IActionResult> Edit(PolicyType type)
|
||||
{
|
||||
var orgId = _enterprisePortalCurrentContext.SelectedOrganizationId;
|
||||
if (orgId == null)
|
||||
{
|
||||
return Redirect("~");
|
||||
}
|
||||
|
||||
if (!_enterprisePortalCurrentContext.SelectedOrganizationDetails.UsePolicies ||
|
||||
!_enterprisePortalCurrentContext.CanManagePoliciesForSelectedOrganization)
|
||||
{
|
||||
return Redirect("~/");
|
||||
}
|
||||
|
||||
var policy = await _policyRepository.GetByOrganizationIdTypeAsync(orgId.Value, type);
|
||||
return BuildPolicyView(policy, type);
|
||||
}
|
||||
|
||||
[HttpPost("/edit/{type}")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Edit(PolicyType type, PolicyEditModel model)
|
||||
{
|
||||
var orgId = _enterprisePortalCurrentContext.SelectedOrganizationId;
|
||||
if (orgId == null)
|
||||
{
|
||||
return Redirect("~");
|
||||
}
|
||||
|
||||
if (!_enterprisePortalCurrentContext.SelectedOrganizationDetails.UsePolicies ||
|
||||
!_enterprisePortalCurrentContext.CanManagePoliciesForSelectedOrganization)
|
||||
{
|
||||
return Redirect("~/");
|
||||
}
|
||||
|
||||
await ValidateDependentPolicies(type, orgId, model.Enabled);
|
||||
var policy = await _policyRepository.GetByOrganizationIdTypeAsync(orgId.Value, type);
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BuildPolicyView(policy, type);
|
||||
}
|
||||
|
||||
if (policy == null)
|
||||
{
|
||||
policy = model.ToPolicy(type, orgId.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
policy = model.ToPolicy(policy);
|
||||
}
|
||||
|
||||
var userId = _userService.GetProperUserId(User);
|
||||
await _policyService.SaveAsync(policy, _userService, _organizationService, userId);
|
||||
return RedirectToAction("Edit", new { type });
|
||||
}
|
||||
|
||||
private IActionResult BuildPolicyView(Policy policy, PolicyType type)
|
||||
{
|
||||
if (policy == null)
|
||||
{
|
||||
return View(new PolicyEditModel(type, _i18nService));
|
||||
}
|
||||
else
|
||||
{
|
||||
return View(new PolicyEditModel(policy, _i18nService));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ValidateDependentPolicies(PolicyType type, Guid? orgId, bool enabled)
|
||||
{
|
||||
if (orgId == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(orgId), "OrgId cannot be null");
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case PolicyType.MasterPassword:
|
||||
case PolicyType.PasswordGenerator:
|
||||
case PolicyType.TwoFactorAuthentication:
|
||||
case PolicyType.PersonalOwnership:
|
||||
case PolicyType.DisableSend:
|
||||
case PolicyType.SendOptions:
|
||||
case PolicyType.ResetPassword:
|
||||
break;
|
||||
|
||||
case PolicyType.SingleOrg:
|
||||
if (enabled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var requireSso =
|
||||
await _policyRepository.GetByOrganizationIdTypeAsync(orgId.Value, PolicyType.RequireSso);
|
||||
if (requireSso?.Enabled == true)
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, _i18nService.T("DisableRequireSsoError"));
|
||||
}
|
||||
break;
|
||||
|
||||
case PolicyType.RequireSso:
|
||||
if (!enabled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var singleOrg = await _policyRepository.GetByOrganizationIdTypeAsync(orgId.Value, PolicyType.SingleOrg);
|
||||
if (singleOrg?.Enabled != true)
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, _i18nService.T("RequireSsoPolicyReqError"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -39,9 +39,6 @@ namespace Bit.Portal
|
||||
public bool OwnerForSelectedOrganization =>
|
||||
SelectedOrganizationDetails?.Type == Core.Enums.OrganizationUserType.Owner;
|
||||
|
||||
public bool CanManagePoliciesForSelectedOrganization =>
|
||||
AdminForSelectedOrganization || SelectedOrganizationDetailsPermissions.ManagePolicies == true;
|
||||
|
||||
public bool CanManageSsoForSelectedOrganization =>
|
||||
AdminForSelectedOrganization || SelectedOrganizationDetailsPermissions.ManageSso == true;
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Portal.Models
|
||||
{
|
||||
public class MasterPasswordDataModel
|
||||
{
|
||||
[Display(Name = "MinimumLength")]
|
||||
[Range(8, int.MaxValue, ErrorMessage = "MasterPasswordMinLengthError")]
|
||||
public int? MinLength { get; set; }
|
||||
[Display(Name = "MinimumComplexityScore")]
|
||||
public int? MinComplexity { get; set; }
|
||||
[Display(Name = "UppercaseAZ")]
|
||||
public bool RequireUpper { get; set; }
|
||||
[Display(Name = "LowercaseAZ")]
|
||||
public bool RequireLower { get; set; }
|
||||
[Display(Name = "Numbers09")]
|
||||
public bool RequireNumbers { get; set; }
|
||||
[Display(Name = "SpecialCharacters")]
|
||||
public bool RequireSpecial { get; set; }
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Portal.Models
|
||||
{
|
||||
public class PasswordGeneratorDataModel
|
||||
{
|
||||
// Shared
|
||||
[Display(Name = "MinimumLength")]
|
||||
[Range(5, 128)]
|
||||
public int? MinLength { get; set; }
|
||||
[Display(Name = "DefaultType")]
|
||||
public string DefaultType { get; set; }
|
||||
// PG - Password
|
||||
[Display(Name = "UppercaseAZ")]
|
||||
public bool UseUpper { get; set; }
|
||||
[Display(Name = "LowercaseAZ")]
|
||||
public bool UseLower { get; set; }
|
||||
[Display(Name = "Numbers09")]
|
||||
public bool UseNumbers { get; set; }
|
||||
[Display(Name = "SpecialCharacters")]
|
||||
public bool UseSpecial { get; set; }
|
||||
[Display(Name = "MinimumNumbers")]
|
||||
[Range(0, 9)]
|
||||
public int? MinNumbers { get; set; }
|
||||
[Display(Name = "MinimumSpecial")]
|
||||
[Range(0, 9)]
|
||||
public int? MinSpecial { get; set; }
|
||||
// PG - Passphrase
|
||||
[Display(Name = "MinimumNumberOfWords")]
|
||||
[Range(3, 20)]
|
||||
public int? MinNumberWords { get; set; }
|
||||
[Display(Name = "Capitalize")]
|
||||
public bool Capitalize { get; set; }
|
||||
[Display(Name = "IncludeNumber")]
|
||||
public bool IncludeNumber { get; set; }
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Table;
|
||||
|
||||
namespace Bit.Portal.Models
|
||||
{
|
||||
public class PoliciesModel
|
||||
{
|
||||
public PoliciesModel(ICollection<Policy> policies, OrganizationUserOrganizationDetails selectedOrgDetails)
|
||||
{
|
||||
if (policies == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var policyDict = policies?.ToDictionary(p => p.Type);
|
||||
Policies = new List<PolicyModel>();
|
||||
|
||||
foreach (var type in Enum.GetValues(typeof(PolicyType)).Cast<PolicyType>())
|
||||
{
|
||||
if (type == PolicyType.RequireSso && !selectedOrgDetails.UseSso)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type == PolicyType.ResetPassword && !selectedOrgDetails.UseResetPassword)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var enabled = policyDict.ContainsKey(type) ? policyDict[type].Enabled : false;
|
||||
Policies.Add(new PolicyModel(type, enabled));
|
||||
}
|
||||
}
|
||||
|
||||
public List<PolicyModel> Policies { get; set; }
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
|
||||
namespace Bit.Portal.Models
|
||||
{
|
||||
public class PolicyEditModel : PolicyModel
|
||||
{
|
||||
public PolicyEditModel() { }
|
||||
|
||||
public PolicyEditModel(PolicyType type, II18nService i18nService)
|
||||
: base(type, false)
|
||||
{
|
||||
// Inject service and create static lists
|
||||
TranslateStrings(i18nService);
|
||||
}
|
||||
|
||||
public PolicyEditModel(Policy model, II18nService i18nService)
|
||||
: base(model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Inject service and create static lists
|
||||
TranslateStrings(i18nService);
|
||||
|
||||
if (model.Data != null)
|
||||
{
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
};
|
||||
|
||||
switch (model.Type)
|
||||
{
|
||||
case PolicyType.MasterPassword:
|
||||
MasterPasswordDataModel = JsonSerializer.Deserialize<MasterPasswordDataModel>(model.Data, options);
|
||||
break;
|
||||
case PolicyType.PasswordGenerator:
|
||||
PasswordGeneratorDataModel = JsonSerializer.Deserialize<PasswordGeneratorDataModel>(model.Data, options);
|
||||
break;
|
||||
case PolicyType.SendOptions:
|
||||
SendOptionsDataModel = JsonSerializer.Deserialize<SendOptionsPolicyData>(model.Data, options);
|
||||
break;
|
||||
case PolicyType.ResetPassword:
|
||||
ResetPasswordDataModel =
|
||||
JsonSerializer.Deserialize<ResetPasswordDataModel>(model.Data, options);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MasterPasswordDataModel MasterPasswordDataModel { get; set; }
|
||||
public PasswordGeneratorDataModel PasswordGeneratorDataModel { get; set; }
|
||||
public SendOptionsPolicyData SendOptionsDataModel { get; set; }
|
||||
public ResetPasswordDataModel ResetPasswordDataModel { get; set; }
|
||||
public List<SelectListItem> Complexities { get; set; }
|
||||
public List<SelectListItem> DefaultTypes { get; set; }
|
||||
public string EnableCheckboxText { get; set; }
|
||||
|
||||
public Policy ToPolicy(PolicyType type, Guid organizationId)
|
||||
{
|
||||
return ToPolicy(new Policy
|
||||
{
|
||||
Type = type,
|
||||
OrganizationId = organizationId
|
||||
});
|
||||
}
|
||||
|
||||
public Policy ToPolicy(Policy existingPolicy)
|
||||
{
|
||||
existingPolicy.Enabled = Enabled;
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
};
|
||||
switch (existingPolicy.Type)
|
||||
{
|
||||
case PolicyType.MasterPassword:
|
||||
existingPolicy.Data = JsonSerializer.Serialize(MasterPasswordDataModel, options);
|
||||
break;
|
||||
case PolicyType.PasswordGenerator:
|
||||
existingPolicy.Data = JsonSerializer.Serialize(PasswordGeneratorDataModel, options);
|
||||
break;
|
||||
case PolicyType.SendOptions:
|
||||
existingPolicy.Data = JsonSerializer.Serialize(SendOptionsDataModel, options);
|
||||
break;
|
||||
case PolicyType.ResetPassword:
|
||||
existingPolicy.Data = JsonSerializer.Serialize(ResetPasswordDataModel, options);
|
||||
break;
|
||||
case PolicyType.SingleOrg:
|
||||
case PolicyType.TwoFactorAuthentication:
|
||||
case PolicyType.RequireSso:
|
||||
case PolicyType.PersonalOwnership:
|
||||
case PolicyType.DisableSend:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
return existingPolicy;
|
||||
}
|
||||
|
||||
public void TranslateStrings(II18nService i18nService)
|
||||
{
|
||||
Complexities = new List<SelectListItem>
|
||||
{
|
||||
new SelectListItem { Value = null, Text = "--" + i18nService.T("Select") + "--"},
|
||||
new SelectListItem { Value = "0", Text = i18nService.T("Weak") + " (0)" },
|
||||
new SelectListItem { Value = "1", Text = i18nService.T("Weak") + " (1)" },
|
||||
new SelectListItem { Value = "2", Text = i18nService.T("Weak") + " (2)" },
|
||||
new SelectListItem { Value = "3", Text = i18nService.T("Good") + " (3)" },
|
||||
new SelectListItem { Value = "4", Text = i18nService.T("Strong") + " (4)" },
|
||||
};
|
||||
DefaultTypes = new List<SelectListItem>
|
||||
{
|
||||
new SelectListItem { Value = null, Text = i18nService.T("UserPreference") },
|
||||
new SelectListItem { Value = "password", Text = i18nService.T("Password") },
|
||||
new SelectListItem { Value = "passphrase", Text = i18nService.T("Passphrase") },
|
||||
};
|
||||
EnableCheckboxText = PolicyType == PolicyType.PersonalOwnership
|
||||
? i18nService.T("PersonalOwnershipCheckboxDesc") : i18nService.T("Enabled");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Table;
|
||||
|
||||
namespace Bit.Portal.Models
|
||||
{
|
||||
public class PolicyModel
|
||||
{
|
||||
public PolicyModel() { }
|
||||
|
||||
public PolicyModel(Policy policy)
|
||||
: this(policy.Type, policy.Enabled)
|
||||
{ }
|
||||
|
||||
public PolicyModel(PolicyType policyType, bool enabled)
|
||||
{
|
||||
switch (policyType)
|
||||
{
|
||||
case PolicyType.TwoFactorAuthentication:
|
||||
NameKey = "TwoStepLogin";
|
||||
DescriptionKey = "TwoStepLoginDescription";
|
||||
break;
|
||||
case PolicyType.MasterPassword:
|
||||
NameKey = "MasterPassword";
|
||||
DescriptionKey = "MasterPasswordDescription";
|
||||
break;
|
||||
case PolicyType.PasswordGenerator:
|
||||
NameKey = "PasswordGenerator";
|
||||
DescriptionKey = "PasswordGeneratorDescription";
|
||||
break;
|
||||
case PolicyType.SingleOrg:
|
||||
NameKey = "SingleOrganization";
|
||||
DescriptionKey = "SingleOrganizationDescription";
|
||||
break;
|
||||
case PolicyType.RequireSso:
|
||||
NameKey = "RequireSso";
|
||||
DescriptionKey = "RequireSsoDescription";
|
||||
break;
|
||||
case PolicyType.PersonalOwnership:
|
||||
NameKey = "PersonalOwnership";
|
||||
DescriptionKey = "PersonalOwnershipDescription";
|
||||
break;
|
||||
case PolicyType.DisableSend:
|
||||
NameKey = "DisableSend";
|
||||
DescriptionKey = "DisableSendDescription";
|
||||
break;
|
||||
case PolicyType.SendOptions:
|
||||
NameKey = "SendOptions";
|
||||
DescriptionKey = "SendOptionsDescription";
|
||||
break;
|
||||
case PolicyType.ResetPassword:
|
||||
NameKey = "ResetPassword";
|
||||
DescriptionKey = "ResetPasswordDescription";
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
PolicyType = policyType;
|
||||
Enabled = enabled;
|
||||
}
|
||||
|
||||
public string NameKey { get; set; }
|
||||
public string DescriptionKey { get; set; }
|
||||
public PolicyType PolicyType { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
}
|
@ -18,14 +18,4 @@
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (EnterprisePortalCurrentContext.SelectedOrganizationDetails.UsePolicies &&
|
||||
EnterprisePortalCurrentContext.CanManagePoliciesForSelectedOrganization)
|
||||
{
|
||||
<div class="col">
|
||||
<a class="card p-5 border border-primary" asp-area="" asp-controller="Policies" asp-action="Index">
|
||||
<h2 class="card-title text-center">@i18nService.T("Policies")</h2>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
@ -1,250 +0,0 @@
|
||||
@using Bit.Core.Enums
|
||||
@model PolicyEditModel
|
||||
@inject Bit.Core.Services.II18nService i18nService
|
||||
@{
|
||||
ViewData["Title"] = i18nService.T("EditPolicy", i18nService.T(Model.NameKey));
|
||||
}
|
||||
|
||||
<div class="page-header">
|
||||
<h1>@i18nService.T("EditPolicy", i18nService.T(Model.NameKey))</h1>
|
||||
</div>
|
||||
<p>@i18nService.T(Model.DescriptionKey)</p>
|
||||
|
||||
<form method="post" id="edit-form">
|
||||
@if (Model.PolicyType == PolicyType.TwoFactorAuthentication)
|
||||
{
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("EditPolicyTwoStepLoginWarning")
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.SingleOrg)
|
||||
{
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("SingleOrganizationPolicyWarning")
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.RequireSso)
|
||||
{
|
||||
<div class="callout callout-success" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-lightbulb-o" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Prerequisite")
|
||||
</h3>
|
||||
@i18nService.T("RequireSsoPolicyReq")
|
||||
</div>
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("RequireSsoExemption")
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.PersonalOwnership)
|
||||
{
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("PersonalOwnershipExemption")
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.DisableSend)
|
||||
{
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("DisableSendExemption")
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.SendOptions)
|
||||
{
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("SendOptionsExemption")
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.ResetPassword)
|
||||
{
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("ResetPasswordWarning")
|
||||
</div>
|
||||
}
|
||||
|
||||
<div asp-validation-summary="ModelOnly" class="alert alert-danger"></div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="Enabled">
|
||||
<label class="form-check-label" asp-for="Enabled">@Model.EnableCheckboxText</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (Model.PolicyType == PolicyType.MasterPassword)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-6 form-group">
|
||||
<label asp-for="MasterPasswordDataModel.MinComplexity"></label>
|
||||
<select asp-for="MasterPasswordDataModel.MinComplexity" asp-items="Model.Complexities"
|
||||
class="form-control"></select>
|
||||
</div>
|
||||
<div class="col-6 form-group">
|
||||
<label asp-for="MasterPasswordDataModel.MinLength"></label>
|
||||
<input class="form-control" type="number" asp-for="MasterPasswordDataModel.MinLength">
|
||||
<span asp-validation-for="MasterPasswordDataModel.MinLength" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="MasterPasswordDataModel.RequireUpper">
|
||||
<label class="form-check-label" asp-for="MasterPasswordDataModel.RequireUpper"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="MasterPasswordDataModel.RequireLower">
|
||||
<label class="form-check-label" asp-for="MasterPasswordDataModel.RequireLower"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="MasterPasswordDataModel.RequireNumbers">
|
||||
<label class="form-check-label" asp-for="MasterPasswordDataModel.RequireNumbers"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="MasterPasswordDataModel.RequireSpecial">
|
||||
<label class="form-check-label" asp-for="MasterPasswordDataModel.RequireSpecial"></label>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.PasswordGenerator)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-6 form-group mb-0">
|
||||
<label asp-for="PasswordGeneratorDataModel.DefaultType"></label>
|
||||
<select asp-for="PasswordGeneratorDataModel.DefaultType" asp-items="Model.DefaultTypes"
|
||||
class="form-control"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-section">
|
||||
<h2>@i18nService.T("Password")</h2>
|
||||
<div class="row">
|
||||
<div class="col-6 form-group">
|
||||
<label asp-for="PasswordGeneratorDataModel.MinLength"></label>
|
||||
<input class="form-control" type="number" asp-for="PasswordGeneratorDataModel.MinLength">
|
||||
<span asp-validation-for="PasswordGeneratorDataModel.MinLength" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 form-group">
|
||||
<label asp-for="PasswordGeneratorDataModel.MinNumbers"></label>
|
||||
<input class="form-control" type="number" asp-for="PasswordGeneratorDataModel.MinNumbers">
|
||||
<span asp-validation-for="PasswordGeneratorDataModel.MinNumbers" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="col-6 form-group">
|
||||
<label asp-for="PasswordGeneratorDataModel.MinSpecial"></label>
|
||||
<input class="form-control" type="number" asp-for="PasswordGeneratorDataModel.MinSpecial">
|
||||
<span asp-validation-for="PasswordGeneratorDataModel.MinSpecial" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="PasswordGeneratorDataModel.UseUpper">
|
||||
<label class="form-check-label" asp-for="PasswordGeneratorDataModel.UseUpper"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="PasswordGeneratorDataModel.UseLower">
|
||||
<label class="form-check-label" asp-for="PasswordGeneratorDataModel.UseLower"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="PasswordGeneratorDataModel.UseNumbers">
|
||||
<label class="form-check-label" asp-for="PasswordGeneratorDataModel.UseNumbers"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="PasswordGeneratorDataModel.UseSpecial">
|
||||
<label class="form-check-label" asp-for="PasswordGeneratorDataModel.UseSpecial"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-section">
|
||||
<h2>@i18nService.T("Passphrase")</h2>
|
||||
<div class="row">
|
||||
<div class="col-6 form-group">
|
||||
<label asp-for="PasswordGeneratorDataModel.MinNumberWords"></label>
|
||||
<input class="form-control" type="number" asp-for="PasswordGeneratorDataModel.MinNumberWords">
|
||||
<span asp-validation-for="PasswordGeneratorDataModel.MinNumberWords" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="PasswordGeneratorDataModel.Capitalize">
|
||||
<label class="form-check-label" asp-for="PasswordGeneratorDataModel.Capitalize"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="PasswordGeneratorDataModel.IncludeNumber">
|
||||
<label class="form-check-label" asp-for="PasswordGeneratorDataModel.IncludeNumber"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.SendOptions)
|
||||
{
|
||||
<div class="config-section">
|
||||
<h2>@i18nService.T("Options")</h2>
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="SendOptionsDataModel.DisableHideEmail">
|
||||
<label class="form-check-label" asp-for="SendOptionsDataModel.DisableHideEmail"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.PolicyType == PolicyType.ResetPassword)
|
||||
{
|
||||
<div class="config-section">
|
||||
<h2>@i18nService.T("ResetPasswordAutoEnroll")</h2>
|
||||
<p>@i18nService.T("ResetPasswordAutoEnrollDescription")</p>
|
||||
<div class="callout callout-warning" role="alert">
|
||||
<h3 class="callout-heading">
|
||||
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
|
||||
@i18nService.T("Warning")
|
||||
</h3>
|
||||
@i18nService.T("ResetPasswordAutoEnrollWarning")
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" asp-for="ResetPasswordDataModel.AutoEnrollEnabled">
|
||||
<label class="form-check-label" asp-for="ResetPasswordDataModel.AutoEnrollEnabled"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="d-flex">
|
||||
<button type="submit" class="btn btn-primary">@i18nService.T("Save")</button>
|
||||
<a class="btn btn-outline-secondary ml-1" asp-controller="Policies" asp-action="Index">@i18nService.T("Cancel")</a>
|
||||
</div>
|
||||
</form>
|
@ -1,29 +0,0 @@
|
||||
@model PoliciesModel
|
||||
@inject Bit.Core.Services.II18nService i18nService
|
||||
@{
|
||||
ViewData["Title"] = i18nService.T("Policies");
|
||||
}
|
||||
|
||||
<div class="page-header">
|
||||
<h1>@i18nService.T("Policies")</h1>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<tbody>
|
||||
@foreach (var policyModel in Model.Policies)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<a asp-action="Edit" asp-route-type="@policyModel.PolicyType">@i18nService.T(policyModel.NameKey)</a>
|
||||
@if (policyModel.Enabled)
|
||||
{
|
||||
<span class="badge badge-success">@i18nService.T("Enabled")</span>
|
||||
}
|
||||
<small class="text-muted d-block">@i18nService.T(policyModel.DescriptionKey)</small>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
@ -31,8 +31,7 @@
|
||||
{
|
||||
<div class="collapse navbar-collapse" id="navbarCollapse">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
@if (EnterprisePortalCurrentContext.SelectedOrganizationDetails.UseSso &&
|
||||
EnterprisePortalCurrentContext.CanManagePoliciesForSelectedOrganization)
|
||||
@if (EnterprisePortalCurrentContext.SelectedOrganizationDetails.UseSso)
|
||||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" asp-area="" asp-controller="Sso" asp-action="Index">
|
||||
@ -40,16 +39,6 @@
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
|
||||
@if (EnterprisePortalCurrentContext.SelectedOrganizationDetails.UsePolicies &&
|
||||
EnterprisePortalCurrentContext.CanManagePoliciesForSelectedOrganization)
|
||||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" asp-area="" asp-controller="Policies" asp-action="Index">
|
||||
@i18nService.T("Policies")
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user