Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SM-114: Add create & update project endpoints #2251

Merged
merged 19 commits into from
Sep 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5d674f3
SM-114: Initial commit with create project endpoint (for SM)
coltonhurst Sep 7, 2022
1ceb723
SM-114: Add Update Project route (for SM)
coltonhurst Sep 7, 2022
39d36bd
SM-114: Fix file encodings
coltonhurst Sep 7, 2022
5876cdc
Fix DI issue for SM Project Create/Update commands
coltonhurst Sep 8, 2022
78f3a8c
Fix import ordering for linter
coltonhurst Sep 8, 2022
a10024b
SM-114: Remove unneeded lines setting DeletedDate, as it should alrea…
coltonhurst Sep 13, 2022
befcc48
Merge branch 'sm/secrets-feature' into SM-114
coltonhurst Sep 13, 2022
5e869d3
SM-114: Only have OrgId in route for CreateProject
coltonhurst Sep 14, 2022
2168823
Remove unneeded using
coltonhurst Sep 14, 2022
e42b4bc
SM-114: Initial commit with create project endpoint (for SM)
coltonhurst Sep 7, 2022
e3f346e
SM-114: Add Update Project route (for SM)
coltonhurst Sep 7, 2022
2c2b2c8
SM-114: Fix file encodings
coltonhurst Sep 7, 2022
cf8b07e
Fix DI issue for SM Project Create/Update commands
coltonhurst Sep 8, 2022
6907b36
Fix import ordering for linter
coltonhurst Sep 8, 2022
283bbfb
SM-114: Remove unneeded lines setting DeletedDate, as it should alrea…
coltonhurst Sep 13, 2022
ed3be34
SM-114: Only have OrgId in route for CreateProject
coltonhurst Sep 14, 2022
e7cbfc2
Remove unneeded using
coltonhurst Sep 14, 2022
7d71c14
Merge branch 'SM-114' of github.com:bitwarden/server into SM-114
coltonhurst Sep 14, 2022
803c60a
Fully remove OrgId from ProjectCreateRequestModel
coltonhurst Sep 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Bit.Core.Entities;
using Bit.Core.Repositories;
using Bit.Core.SecretManagerFeatures.Projects.Interfaces;

namespace Bit.Commercial.Core.SecretManagerFeatures.Projects
{
public class CreateProjectCommand : ICreateProjectCommand
{
private readonly IProjectRepository _projectRepository;

public CreateProjectCommand(IProjectRepository projectRepository)
{
_projectRepository = projectRepository;
}

public async Task<Project> CreateAsync(Project project)
{
return await _projectRepository.CreateAsync(project);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.SecretManagerFeatures.Projects.Interfaces;

namespace Bit.Commercial.Core.SecretManagerFeatures.Projects
{
public class UpdateProjectCommand : IUpdateProjectCommand
{
private readonly IProjectRepository _projectRepository;

public UpdateProjectCommand(IProjectRepository projectRepository)
{
_projectRepository = projectRepository;
}

public async Task<Project> UpdateAsync(Project project)
{
if (project.Id == default(Guid))
{
throw new BadRequestException("Cannot update project, project does not exist.");
}

var existingProject = await _projectRepository.GetByIdAsync(project.Id);
if (existingProject == null)
{
throw new NotFoundException();
}

project.OrganizationId = existingProject.OrganizationId;
project.CreationDate = existingProject.CreationDate;
project.DeletedDate = existingProject.DeletedDate;
project.RevisionDate = DateTime.UtcNow;

await _projectRepository.ReplaceAsync(project);
return project;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Bit.Commercial.Core.SecretManagerFeatures.Secrets;
using Bit.Commercial.Core.SecretManagerFeatures.Projects;
using Bit.Commercial.Core.SecretManagerFeatures.Secrets;
using Bit.Core.SecretManagerFeatures.Projects.Interfaces;
using Bit.Core.SecretManagerFeatures.Secrets.Interfaces;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -10,6 +12,8 @@ public static void AddSecretManagerServices(this IServiceCollection services)
{
services.AddScoped<ICreateSecretCommand, CreateSecretCommand>();
services.AddScoped<IUpdateSecretCommand, UpdateSecretCommand>();
services.AddScoped<ICreateProjectCommand, CreateProjectCommand>();
services.AddScoped<IUpdateProjectCommand, UpdateProjectCommand>();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@ public async Task<Secret> CreateAsync(Secret secret)
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,3 @@ public async Task<Secret> UpdateAsync(Secret secret)
}
}
}

38 changes: 38 additions & 0 deletions src/Api/Controllers/ProjectsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Bit.Api.SecretManagerFeatures.Models.Request;
using Bit.Api.SecretManagerFeatures.Models.Response;
using Bit.Api.Utilities;
using Bit.Core.Repositories;
using Bit.Core.SecretManagerFeatures.Projects.Interfaces;
using Microsoft.AspNetCore.Mvc;

namespace Bit.Api.Controllers
{
[SecretsManager]
public class ProjectsController : Controller
{
private readonly IProjectRepository _projectRepository;
private readonly ICreateProjectCommand _createProjectCommand;
private readonly IUpdateProjectCommand _updateProjectCommand;

public ProjectsController(IProjectRepository projectRepository, ICreateProjectCommand createProjectCommand, IUpdateProjectCommand updateProjectCommand)
{
_projectRepository = projectRepository;
_createProjectCommand = createProjectCommand;
_updateProjectCommand = updateProjectCommand;
}

[HttpPost("organizations/{organizationId}/projects")]
public async Task<ProjectResponseModel> CreateAsync([FromRoute] Guid organizationId, [FromBody] ProjectCreateRequestModel createRequest)
{
var result = await _createProjectCommand.CreateAsync(createRequest.ToProject(organizationId));
return new ProjectResponseModel(result);
}

[HttpPut("projects/{id}")]
public async Task<ProjectResponseModel> UpdateProjectAsync([FromRoute] Guid id, [FromBody] ProjectUpdateRequestModel updateRequest)
{
var result = await _updateProjectCommand.UpdateAsync(updateRequest.ToProject(id));
return new ProjectResponseModel(result);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Entities;
using Bit.Core.Utilities;

namespace Bit.Api.SecretManagerFeatures.Models.Request
{
public class ProjectCreateRequestModel
{
[Required]
[EncryptedString]
public string Name { get; set; }

public Project ToProject(Guid organizationId)
{
return new Project()
{
OrganizationId = organizationId,
Name = this.Name,
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Entities;
using Bit.Core.Utilities;

namespace Bit.Api.SecretManagerFeatures.Models.Request
{
public class ProjectUpdateRequestModel
{
[Required]
[EncryptedString]
public string Name { get; set; }

public Project ToProject(Guid id)
{
return new Project()
{
Id = id,
Name = this.Name,
};
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,3 @@ public Secret ToSecret(Guid organizationId)
}
}
}

coltonhurst marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,3 @@ public Secret ToSecret(Guid id)
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Bit.Core.Entities;
using Bit.Core.Models.Api;

namespace Bit.Api.SecretManagerFeatures.Models.Response
{
public class ProjectResponseModel : ResponseModel
{
public ProjectResponseModel(Project project, string obj = "project")
: base(obj)
{
if (project == null)
{
throw new ArgumentNullException(nameof(project));
}

Id = project.Id.ToString();
OrganizationId = project.OrganizationId.ToString();
Name = project.Name;
CreationDate = project.CreationDate;
RevisionDate = project.RevisionDate;
}

public string Id { get; set; }

public string OrganizationId { get; set; }

public string Name { get; set; }

public DateTime CreationDate { get; set; }

public DateTime RevisionDate { get; set; }
}
}
1 change: 0 additions & 1 deletion src/Core/Entities/Secret.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class Secret : ITableObject<Guid>

public DateTime? DeletedDate { get; set; }


public void SetNewId()
{
if (Id == default(Guid))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Bit.Core.Entities;

namespace Bit.Core.SecretManagerFeatures.Projects.Interfaces
{
public interface ICreateProjectCommand
{
Task<Project> CreateAsync(Project project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Bit.Core.Entities;

namespace Bit.Core.SecretManagerFeatures.Projects.Interfaces
{
public interface IUpdateProjectCommand
{
Task<Project> UpdateAsync(Project project);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ public interface ICreateSecretCommand
Task<Secret> CreateAsync(Secret secret);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ public interface IUpdateSecretCommand
Task<Secret> UpdateAsync(Secret secret);
}
}