Skip to content

Commit c8b0f72

Browse files
authored
Add an option to bookmark reports and vulnerabilities (#39)
* Add an option to bookmark reports and vulnerabilities
1 parent 4a9a33e commit c8b0f72

File tree

26 files changed

+2050
-122
lines changed

26 files changed

+2050
-122
lines changed

Backend/SorobanSecurityPortalApi/Common/Data/Db.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using SorobanSecurityPortalApi.Models.DbModels;
33
using Microsoft.EntityFrameworkCore;
44
using Microsoft.EntityFrameworkCore.Diagnostics;
5-
using Pgvector;
65

76
namespace SorobanSecurityPortalApi.Common.Data
87
{
@@ -20,6 +19,7 @@ public class Db : DbContext
2019
public DbSet<CategoryModel> Category { get; set; }
2120
public DbSet<FileModel> File { get; set; }
2221
public DbSet<CompanyModel> Company { get; set; }
22+
public DbSet<BookmarkModel> Bookmark { get; set; }
2323

2424

2525
private readonly IDbQuery _dbQuery;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using Microsoft.AspNetCore.Mvc;
3+
using SorobanSecurityPortalApi.Authorization.Attributes;
4+
using SorobanSecurityPortalApi.Common;
5+
using SorobanSecurityPortalApi.Models.DbModels;
6+
using SorobanSecurityPortalApi.Services.ControllersServices;
7+
8+
namespace SorobanSecurityPortalApi.Controllers
9+
{
10+
[ApiController]
11+
[Authorize]
12+
[Route("api/v1/bookmarks")]
13+
public class BookmarkController : ControllerBase
14+
{
15+
private readonly IBookmarkService _bookmarkService;
16+
17+
public BookmarkController(IBookmarkService bookmarkService)
18+
{
19+
_bookmarkService = bookmarkService;
20+
}
21+
22+
[HttpPost]
23+
[Authorize]
24+
public async Task<IActionResult> Add(BookmarkModel bookmarkModel)
25+
{
26+
var result = await _bookmarkService.Add(bookmarkModel);
27+
return Ok(result);
28+
}
29+
30+
[HttpDelete("{id}")]
31+
[Authorize]
32+
public async Task<IActionResult> Delete(int id)
33+
{
34+
await _bookmarkService.Delete(id);
35+
return Ok();
36+
}
37+
38+
[HttpGet]
39+
[Authorize]
40+
public async Task<IActionResult> List()
41+
{
42+
var result = await _bookmarkService.List();
43+
return Ok(result);
44+
}
45+
46+
[HttpGet]
47+
[Route("{id}")]
48+
public async Task<IActionResult> Get(int id)
49+
{
50+
var bookmarks = await _bookmarkService.List();
51+
var bookmark = bookmarks.FirstOrDefault(a => a.Id == id);
52+
if (bookmark == null)
53+
{
54+
return NotFound($"Bookmark with ID {id} not found.");
55+
}
56+
return Ok(bookmark);
57+
}
58+
}
59+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using SorobanSecurityPortalApi.Common.Data;
3+
using SorobanSecurityPortalApi.Models.DbModels;
4+
using SorobanSecurityPortalApi.Models.ViewModels;
5+
6+
namespace SorobanSecurityPortalApi.Data.Processors
7+
{
8+
public class BookmarkProcessor : IBookmarkProcessor
9+
{
10+
private readonly IDbContextFactory<Db> _dbFactory;
11+
12+
public BookmarkProcessor(IDbContextFactory<Db> dbFactory)
13+
{
14+
_dbFactory = dbFactory;
15+
}
16+
17+
public async Task<BookmarkModel> Get(int bookmarkModelId)
18+
{
19+
await using var db = await _dbFactory.CreateDbContextAsync();
20+
var bookmark = await db.Bookmark.FindAsync(bookmarkModelId);
21+
if (bookmark == null)
22+
{
23+
throw new KeyNotFoundException($"Bookmark with ID {bookmarkModelId} not found");
24+
}
25+
return bookmark;
26+
}
27+
28+
public async Task<BookmarkViewModel> Add(BookmarkModel bookmarkModel)
29+
{
30+
await using var db = await _dbFactory.CreateDbContextAsync();
31+
if (bookmarkModel == null)
32+
{
33+
throw new ArgumentNullException(nameof(bookmarkModel), "Bookmark model cannot be null");
34+
}
35+
var title = "";
36+
var description = "";
37+
if (bookmarkModel.BookmarkType == BookmarkTypeEnum.Report)
38+
{
39+
var report = await db.Report.FindAsync(bookmarkModel.ItemId);
40+
if (report == null)
41+
{
42+
throw new KeyNotFoundException($"Report with ID {bookmarkModel.ItemId} not found");
43+
}
44+
title = report.Name;
45+
}
46+
else if (bookmarkModel.BookmarkType == BookmarkTypeEnum.Vulnerability)
47+
{
48+
var vulnerability = await db.Vulnerability.FindAsync(bookmarkModel.ItemId);
49+
if (vulnerability == null)
50+
{
51+
throw new KeyNotFoundException($"Vulnerability with ID {bookmarkModel.ItemId} not found");
52+
}
53+
title = vulnerability.Title;
54+
description = vulnerability.Description;
55+
}
56+
else
57+
{
58+
throw new ArgumentException($"Invalid BookmarkType: {bookmarkModel.BookmarkType}");
59+
}
60+
db.Bookmark.Add(bookmarkModel);
61+
await db.SaveChangesAsync();
62+
return new BookmarkViewModel
63+
{
64+
Id = bookmarkModel.Id,
65+
ItemId = bookmarkModel.ItemId,
66+
BookmarkType = bookmarkModel.BookmarkType,
67+
Title = title,
68+
Description = description
69+
};
70+
}
71+
72+
public async Task Delete(int bookmarkModelId)
73+
{
74+
await using var db = await _dbFactory.CreateDbContextAsync();
75+
var bookmark = await db.Bookmark.FindAsync(bookmarkModelId);
76+
if (bookmark == null)
77+
{
78+
throw new KeyNotFoundException($"Bookmark with ID {bookmarkModelId} not found");
79+
}
80+
db.Bookmark.Remove(bookmark);
81+
await db.SaveChangesAsync();
82+
}
83+
84+
public async Task<List<BookmarkViewModel>> List()
85+
{
86+
await using var db = await _dbFactory.CreateDbContextAsync();
87+
var bookmarks = await db.Bookmark.OrderByDescending(x => x.Id).ToListAsync();
88+
var res = new List<BookmarkViewModel>();
89+
foreach (var bookmark in bookmarks)
90+
{
91+
if (bookmark.BookmarkType == BookmarkTypeEnum.Report)
92+
{
93+
var report = await db.Report.FindAsync(bookmark.ItemId);
94+
if (report == null)
95+
{
96+
throw new Exception($"Report with ID {bookmark.ItemId} not found for bookmark ID {bookmark.Id}");
97+
}
98+
res.Add(new BookmarkViewModel
99+
{
100+
Id = bookmark.Id,
101+
ItemId = report.Id,
102+
BookmarkType = bookmark.BookmarkType,
103+
Title = report.Name,
104+
Description = ""
105+
});
106+
} else
107+
{
108+
var vulnerability = await db.Vulnerability.FindAsync(bookmark.ItemId);
109+
if (vulnerability == null)
110+
{
111+
throw new Exception($"Vulnerability with ID {bookmark.ItemId} not found for bookmark ID {bookmark.Id}");
112+
}
113+
res.Add(new BookmarkViewModel
114+
{
115+
Id = bookmark.Id,
116+
ItemId = vulnerability.Id,
117+
BookmarkType = bookmark.BookmarkType,
118+
Title = vulnerability.Title,
119+
Description = vulnerability.Description
120+
});
121+
}
122+
}
123+
return res;
124+
}
125+
126+
}
127+
128+
public interface IBookmarkProcessor
129+
{
130+
Task<BookmarkModel> Get(int bookmarkModelId);
131+
Task<BookmarkViewModel> Add(BookmarkModel bookmarkModel);
132+
Task Delete(int bookmarkModelId);
133+
Task<List<BookmarkViewModel>> List();
134+
}
135+
}

0 commit comments

Comments
 (0)