mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 15:42:48 -05:00
[SM-706] Extract Authorization From Create/Update Secret Commands (#2896)
* Extract authorization from commands * Swap to request model validation. * Swap to pattern detection
This commit is contained in:
@ -6,6 +6,7 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Identity;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.SecretsManager.AuthorizationRequirements;
|
||||
using Bit.Core.SecretsManager.Commands.Secrets.Interfaces;
|
||||
using Bit.Core.SecretsManager.Repositories;
|
||||
using Bit.Core.Services;
|
||||
@ -32,6 +33,7 @@ public class SecretsController : Controller
|
||||
private readonly IUserService _userService;
|
||||
private readonly IEventService _eventService;
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
public SecretsController(
|
||||
ICurrentContext currentContext,
|
||||
@ -43,7 +45,8 @@ public class SecretsController : Controller
|
||||
IDeleteSecretCommand deleteSecretCommand,
|
||||
IUserService userService,
|
||||
IEventService eventService,
|
||||
IReferenceEventService referenceEventService)
|
||||
IReferenceEventService referenceEventService,
|
||||
IAuthorizationService authorizationService)
|
||||
{
|
||||
_currentContext = currentContext;
|
||||
_projectRepository = projectRepository;
|
||||
@ -55,6 +58,7 @@ public class SecretsController : Controller
|
||||
_userService = userService;
|
||||
_eventService = eventService;
|
||||
_referenceEventService = referenceEventService;
|
||||
_authorizationService = authorizationService;
|
||||
|
||||
}
|
||||
|
||||
@ -78,18 +82,14 @@ public class SecretsController : Controller
|
||||
[HttpPost("organizations/{organizationId}/secrets")]
|
||||
public async Task<SecretResponseModel> CreateAsync([FromRoute] Guid organizationId, [FromBody] SecretCreateRequestModel createRequest)
|
||||
{
|
||||
if (!_currentContext.AccessSecretsManager(organizationId))
|
||||
var secret = createRequest.ToSecret(organizationId);
|
||||
var authorizationResult = await _authorizationService.AuthorizeAsync(User, secret, SecretOperations.Create);
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if (createRequest.ProjectIds != null && createRequest.ProjectIds.Length > 1)
|
||||
{
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
var userId = _userService.GetProperUserId(User).Value;
|
||||
var result = await _createSecretCommand.CreateAsync(createRequest.ToSecret(organizationId), userId);
|
||||
var result = await _createSecretCommand.CreateAsync(secret);
|
||||
|
||||
// Creating a secret means you have read & write permission.
|
||||
return new SecretResponseModel(result, true, true);
|
||||
@ -148,14 +148,20 @@ public class SecretsController : Controller
|
||||
[HttpPut("secrets/{id}")]
|
||||
public async Task<SecretResponseModel> UpdateSecretAsync([FromRoute] Guid id, [FromBody] SecretUpdateRequestModel updateRequest)
|
||||
{
|
||||
if (updateRequest.ProjectIds != null && updateRequest.ProjectIds.Length > 1)
|
||||
var secret = await _secretRepository.GetByIdAsync(id);
|
||||
if (secret == null)
|
||||
{
|
||||
throw new BadRequestException();
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var userId = _userService.GetProperUserId(User).Value;
|
||||
var secret = updateRequest.ToSecret(id);
|
||||
var result = await _updateSecretCommand.UpdateAsync(secret, userId);
|
||||
var updatedSecret = updateRequest.ToSecret(id, secret.OrganizationId);
|
||||
var authorizationResult = await _authorizationService.AuthorizeAsync(User, updatedSecret, SecretOperations.Update);
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var result = await _updateSecretCommand.UpdateAsync(updatedSecret);
|
||||
|
||||
// Updating a secret means you have read & write permission.
|
||||
return new SecretResponseModel(result, true, true);
|
||||
|
@ -4,7 +4,7 @@ using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.SecretsManager.Models.Request;
|
||||
|
||||
public class SecretCreateRequestModel
|
||||
public class SecretCreateRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
@ -32,4 +32,14 @@ public class SecretCreateRequestModel
|
||||
Projects = ProjectIds != null && ProjectIds.Any() ? ProjectIds.Select(x => new Project() { Id = x }).ToList() : null,
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (ProjectIds is { Length: > 1 })
|
||||
{
|
||||
yield return new ValidationResult(
|
||||
$"Only one project assignment is supported.",
|
||||
new[] { nameof(ProjectIds) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.SecretsManager.Models.Request;
|
||||
|
||||
public class SecretUpdateRequestModel
|
||||
public class SecretUpdateRequestModel : IValidatableObject
|
||||
{
|
||||
[Required]
|
||||
[EncryptedString]
|
||||
@ -20,11 +20,12 @@ public class SecretUpdateRequestModel
|
||||
|
||||
public Guid[] ProjectIds { get; set; }
|
||||
|
||||
public Secret ToSecret(Guid id)
|
||||
public Secret ToSecret(Guid id, Guid organizationId)
|
||||
{
|
||||
return new Secret()
|
||||
{
|
||||
Id = id,
|
||||
OrganizationId = organizationId,
|
||||
Key = Key,
|
||||
Value = Value,
|
||||
Note = Note,
|
||||
@ -32,4 +33,14 @@ public class SecretUpdateRequestModel
|
||||
Projects = ProjectIds != null && ProjectIds.Any() ? ProjectIds.Select(x => new Project() { Id = x }).ToList() : null,
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (ProjectIds is { Length: > 1 })
|
||||
{
|
||||
yield return new ValidationResult(
|
||||
$"Only one project assignment is supported.",
|
||||
new[] { nameof(ProjectIds) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user