1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 23:52:50 -05:00

[PM-14245] Remove policy definitions feature flag (#5095)

* Remove PolicyService.SaveAsync and use command instead

* Delete feature flag definition

* Add public api integration tests
This commit is contained in:
Thomas Rittson
2024-12-04 11:50:47 +10:00
committed by GitHub
parent c9aa61b0cf
commit 44b687922d
17 changed files with 290 additions and 1126 deletions

View File

@ -6,8 +6,8 @@ using Bit.Core;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains.Interfaces;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.AdminConsole.Services;
using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Context;
using Bit.Core.Enums;
@ -28,7 +28,6 @@ namespace Bit.Api.AdminConsole.Controllers;
public class PoliciesController : Controller
{
private readonly IPolicyRepository _policyRepository;
private readonly IPolicyService _policyService;
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IUserService _userService;
private readonly ICurrentContext _currentContext;
@ -37,10 +36,10 @@ public class PoliciesController : Controller
private readonly IDataProtectorTokenFactory<OrgUserInviteTokenable> _orgUserInviteTokenDataFactory;
private readonly IFeatureService _featureService;
private readonly IOrganizationHasVerifiedDomainsQuery _organizationHasVerifiedDomainsQuery;
private readonly ISavePolicyCommand _savePolicyCommand;
public PoliciesController(
IPolicyRepository policyRepository,
IPolicyService policyService,
IOrganizationUserRepository organizationUserRepository,
IUserService userService,
ICurrentContext currentContext,
@ -48,10 +47,10 @@ public class PoliciesController : Controller
IDataProtectionProvider dataProtectionProvider,
IDataProtectorTokenFactory<OrgUserInviteTokenable> orgUserInviteTokenDataFactory,
IFeatureService featureService,
IOrganizationHasVerifiedDomainsQuery organizationHasVerifiedDomainsQuery)
IOrganizationHasVerifiedDomainsQuery organizationHasVerifiedDomainsQuery,
ISavePolicyCommand savePolicyCommand)
{
_policyRepository = policyRepository;
_policyService = policyService;
_organizationUserRepository = organizationUserRepository;
_userService = userService;
_currentContext = currentContext;
@ -62,6 +61,7 @@ public class PoliciesController : Controller
_orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory;
_featureService = featureService;
_organizationHasVerifiedDomainsQuery = organizationHasVerifiedDomainsQuery;
_savePolicyCommand = savePolicyCommand;
}
[HttpGet("{type}")]
@ -178,25 +178,20 @@ public class PoliciesController : Controller
}
[HttpPut("{type}")]
public async Task<PolicyResponseModel> Put(string orgId, int type, [FromBody] PolicyRequestModel model)
public async Task<PolicyResponseModel> Put(Guid orgId, PolicyType type, [FromBody] PolicyRequestModel model)
{
var orgIdGuid = new Guid(orgId);
if (!await _currentContext.ManagePolicies(orgIdGuid))
if (!await _currentContext.ManagePolicies(orgId))
{
throw new NotFoundException();
}
var policy = await _policyRepository.GetByOrganizationIdTypeAsync(new Guid(orgId), (PolicyType)type);
if (policy == null)
if (type != model.Type)
{
policy = model.ToPolicy(orgIdGuid);
}
else
{
policy = model.ToPolicy(policy);
throw new BadRequestException("Mismatched policy type");
}
var userId = _userService.GetProperUserId(User);
await _policyService.SaveAsync(policy, userId);
var policyUpdate = await model.ToPolicyUpdateAsync(orgId, _currentContext);
var policy = await _savePolicyCommand.SaveAsync(policyUpdate);
return new PolicyResponseModel(policy);
}
}

View File

@ -1,7 +1,9 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.Models.Data;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.Models;
using Bit.Core.Context;
namespace Bit.Api.AdminConsole.Models.Request;
@ -13,19 +15,12 @@ public class PolicyRequestModel
public bool? Enabled { get; set; }
public Dictionary<string, object> Data { get; set; }
public Policy ToPolicy(Guid orgId)
public async Task<PolicyUpdate> ToPolicyUpdateAsync(Guid organizationId, ICurrentContext currentContext) => new()
{
return ToPolicy(new Policy
{
Type = Type.Value,
OrganizationId = orgId
});
}
public Policy ToPolicy(Policy existingPolicy)
{
existingPolicy.Enabled = Enabled.GetValueOrDefault();
existingPolicy.Data = Data != null ? JsonSerializer.Serialize(Data) : null;
return existingPolicy;
}
Type = Type!.Value,
OrganizationId = organizationId,
Data = Data != null ? JsonSerializer.Serialize(Data) : null,
Enabled = Enabled.GetValueOrDefault(),
PerformedBy = new StandardUser(currentContext.UserId!.Value, await currentContext.OrganizationOwner(organizationId))
};
}

View File

@ -3,6 +3,7 @@ using Bit.Api.AdminConsole.Public.Models.Request;
using Bit.Api.AdminConsole.Public.Models.Response;
using Bit.Api.Models.Public.Response;
using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.AdminConsole.Services;
using Bit.Core.Context;
@ -18,15 +19,18 @@ public class PoliciesController : Controller
private readonly IPolicyRepository _policyRepository;
private readonly IPolicyService _policyService;
private readonly ICurrentContext _currentContext;
private readonly ISavePolicyCommand _savePolicyCommand;
public PoliciesController(
IPolicyRepository policyRepository,
IPolicyService policyService,
ICurrentContext currentContext)
ICurrentContext currentContext,
ISavePolicyCommand savePolicyCommand)
{
_policyRepository = policyRepository;
_policyService = policyService;
_currentContext = currentContext;
_savePolicyCommand = savePolicyCommand;
}
/// <summary>
@ -80,17 +84,9 @@ public class PoliciesController : Controller
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task<IActionResult> Put(PolicyType type, [FromBody] PolicyUpdateRequestModel model)
{
var policy = await _policyRepository.GetByOrganizationIdTypeAsync(
_currentContext.OrganizationId.Value, type);
if (policy == null)
{
policy = model.ToPolicy(_currentContext.OrganizationId.Value, type);
}
else
{
policy = model.ToPolicy(policy);
}
await _policyService.SaveAsync(policy, null);
var policyUpdate = model.ToPolicyUpdate(_currentContext.OrganizationId!.Value, type);
var policy = await _savePolicyCommand.SaveAsync(policyUpdate);
var response = new PolicyResponseModel(policy);
return new JsonResult(response);
}

View File

@ -1,26 +1,19 @@
using System.Text.Json;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.Models.Data;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.Models;
using Bit.Core.Enums;
namespace Bit.Api.AdminConsole.Public.Models.Request;
public class PolicyUpdateRequestModel : PolicyBaseModel
{
public Policy ToPolicy(Guid orgId, PolicyType type)
public PolicyUpdate ToPolicyUpdate(Guid organizationId, PolicyType type) => new()
{
return ToPolicy(new Policy
{
OrganizationId = orgId,
Enabled = Enabled.GetValueOrDefault(),
Data = Data != null ? JsonSerializer.Serialize(Data) : null,
Type = type
});
}
public virtual Policy ToPolicy(Policy existingPolicy)
{
existingPolicy.Enabled = Enabled.GetValueOrDefault();
existingPolicy.Data = Data != null ? JsonSerializer.Serialize(Data) : null;
return existingPolicy;
}
Type = type,
OrganizationId = organizationId,
Data = Data != null ? JsonSerializer.Serialize(Data) : null,
Enabled = Enabled.GetValueOrDefault(),
PerformedBy = new SystemUser(EventSystemUser.PublicApi)
};
}

View File

@ -1,8 +1,9 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Bit.Api.Models.Public.Response;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums;
using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace Bit.Api.AdminConsole.Public.Models.Response;
@ -11,6 +12,9 @@ namespace Bit.Api.AdminConsole.Public.Models.Response;
/// </summary>
public class PolicyResponseModel : PolicyBaseModel, IResponseModel
{
[JsonConstructor]
public PolicyResponseModel() { }
public PolicyResponseModel(Policy policy)
{
if (policy == null)