diff options
Diffstat (limited to 'src/marlin.web/Controllers/VCSController.cs')
| -rw-r--r-- | src/marlin.web/Controllers/VCSController.cs | 92 |
1 files changed, 90 insertions, 2 deletions
diff --git a/src/marlin.web/Controllers/VCSController.cs b/src/marlin.web/Controllers/VCSController.cs index 86f655b..7370e0d 100644 --- a/src/marlin.web/Controllers/VCSController.cs +++ b/src/marlin.web/Controllers/VCSController.cs @@ -1,33 +1,47 @@ namespace marlin.web.Controllers; +using System.Text.Json; using core; using core.models; using Data; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Models; +using Services; [Route("vcs")] -public class VCSController(ApplicationDbContext dbContext) : Controller +public class VCSController(ApplicationDbContext dbContext, VersionControlSyncService syncService) : Controller { [HttpGet("list")] public async Task<IActionResult> List(CancellationToken ct) { var items = await dbContext.Sources + .Include(x => x.Branches) .ToListAsync(ct); return this.View(items); } + public record SecretOption(Guid Id, string Label); + [HttpGet("details/{id}")] public async Task<IActionResult> Details(Guid id, CancellationToken ct) { var item = await dbContext.Sources + .Include(x => x.Branches) + .ThenInclude(x => x.Commit) .FirstOrDefaultAsync(x => x.Id == id, ct); if (item == null) return this.NotFound(); - return this.View(item); + // Only Id/Label projected — a secret's Content never needs to leave the secrets pages. + var secretOptions = await dbContext.Secrets + .Where(x => x.SourceId == id) + .Select(x => new SecretOption(x.Id, x.Label)) + .ToListAsync(ct); + + return this.View((item, secretOptions)); } [HttpPost("edit/{id}")] @@ -43,8 +57,10 @@ public class VCSController(ApplicationDbContext dbContext) : Controller item.BranchFilter = vcs.BranchFilter; item.MainBranch = vcs.MainBranch; item.MinPollingInterval = vcs.MinPollingInterval; + item.AccessSecretId = vcs.AccessSecretId; await dbContext.SaveChangesAsync(ct); + await syncService.FetchSources(ct); return this.RedirectToAction("List"); } @@ -62,7 +78,79 @@ public class VCSController(ApplicationDbContext dbContext) : Controller await dbContext.AddAsync(vcs, ct); await dbContext.SaveChangesAsync(ct); + await syncService.FetchSources(ct); return this.RedirectToAction("Details", new { id = vcs.Id }); } + + public record SecretCreateRequest(string Label, string? Kind, bool MayReveal, string ContentJson); + + [HttpGet("details/{sourceId}/secrets/create")] + public async Task<IActionResult> CreateSecret(Guid sourceId, CancellationToken ct) + { + var source = await dbContext.Sources + .FirstOrDefaultAsync(x => x.Id == sourceId, ct); + + if (source == null) + return this.NotFound(); + + return this.View(source); + } + + [HttpPost("details/{sourceId}/secrets/create")] + public async Task<IActionResult> CreateSecretPost(Guid sourceId, SecretCreateRequest request, CancellationToken ct) + { + var source = await dbContext.Sources + .FirstOrDefaultAsync(x => x.Id == sourceId, ct); + + if (source == null) + return this.NotFound(); + + var content = JsonSerializer.Deserialize<Dictionary<string, string>>(request.ContentJson) ?? new(); + + var secret = new VersionControlSecret + { + SourceId = sourceId, + Label = request.Label, + Kind = request.Kind, + MayReveal = request.MayReveal, + Content = content + }; + + await dbContext.Secrets.AddAsync(secret, ct); + await dbContext.SaveChangesAsync(ct); + + return this.RedirectToAction("ListSecret", new { sourceId }); + } + + [HttpGet("details/{sourceId}/secrets/list")] + public async Task<IActionResult> ListSecret(Guid sourceId, CancellationToken ct) + { + var source = await dbContext.Sources + .FirstOrDefaultAsync(x => x.Id == sourceId, ct); + + if (source == null) + return this.NotFound(); + + var items = await dbContext.Secrets + .Where(x => x.SourceId == source.Id) + .ToListAsync<ISecret>(ct); + + return this.View((source, items)); + } + + [HttpPost("details/{sourceId}/secrets/delete/{id}")] + public async Task<IActionResult> DeleteSecret(Guid sourceId, Guid id, CancellationToken ct) + { + var secret = await dbContext.Secrets + .FirstOrDefaultAsync(x => x.SourceId == sourceId && x.Id == id, ct); + + if (secret == null) + return this.NotFound(); + + dbContext.Secrets.Remove(secret); + await dbContext.SaveChangesAsync(ct); + + return this.RedirectToAction("ListSecret", new { sourceId = sourceId }); + } }
\ No newline at end of file |
