diff --git a/Todo.Api/Models/ToDo.cs b/Todo.Api/Models/ToDo.cs new file mode 100644 index 0000000..f0dc15c --- /dev/null +++ b/Todo.Api/Models/ToDo.cs @@ -0,0 +1,18 @@ +using System; + +namespace Todo.Api.Models +{ + // Create ToDo class + public class ToDo + { + public int Id { get; set; } + + public string Title { get; set; } + + public bool IsDone { get; set; } + + public DateTime CreatedDateTime { get; set; } + + public DateTime? CompletedDateTime { get; set; } + } +} \ No newline at end of file diff --git a/Todo.Api/Program.cs b/Todo.Api/Program.cs index aa1fbff..7970084 100644 --- a/Todo.Api/Program.cs +++ b/Todo.Api/Program.cs @@ -1,104 +1,109 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; - -WebApplicationBuilder? builder = WebApplication.CreateBuilder(args); - -// ConfigureServices -builder.Services.AddDbContext(options => - options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); - -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); - -WebApplication app = builder.Build(); - -// Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) -{ - app.UseSwagger(); - app.UseSwaggerUI(); -} - -app.UseHttpsRedirection(); - -// Map endpoint to get ToDos -app.MapGet("/Todos", async (ToDoDbContext dbContext) => -{ - return Results.Ok(await dbContext.ToDos.ToListAsync()); -}); - -// Map endpoint to get ToDo by id -app.MapGet("/Todos/{id}", async (ToDoDbContext dbContext, int id) => -{ - ToDo? toDo = await dbContext.ToDos.FindAsync(id); - if (toDo is null) - { - return Results.NotFound(); - } - - return Results.Ok(toDo); -}); - -// Map endpoint to create ToDo -app.MapPost("/Todos", async (ToDoDbContext dbContext, ToDo toDo) => -{ - await dbContext.ToDos.AddAsync(toDo); - await dbContext.SaveChangesAsync(); - - return Results.Created($"/Todos/{toDo.Id}", toDo); -}); - -// Map endpoint to update ToDo -app.MapPut("/Todos/{id}", async (ToDoDbContext dbContext, int id, ToDo toDo) => -{ - if (await dbContext.ToDos.FindAsync(id) == null) - { - return Results.NotFound(); - } - - toDo.Id = id; - dbContext.ToDos.Update(toDo); - - return Results.NoContent(); -}); - -// Map endpoint to delete ToDo -app.MapDelete("/Todos/{id}", async (ToDoDbContext dbContext, int id) => +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System.Collections.Generic; +using System.Threading.Tasks; +using Todo.Api.Models; + +namespace Todo.Api { - ToDo? toDo = await dbContext.ToDos.FindAsync(id); - if (toDo is null) - { - return Results.NotFound(); - } - - dbContext.ToDos.Remove(toDo); - await dbContext.SaveChangesAsync(); - - return Results.NoContent(); -}); - -await app.RunAsync(); - -// Create ToDo class -public class ToDo -{ - public int Id { get; set; } - - public string Title { get; set; } - - public bool IsDone { get; set; } - - public DateTime CreatedDateTime { get; set; } - - public DateTime? CompletedDateTime { get; set; } -} - -// Create ToDoDbContext with Entity Framework -public class ToDoDbContext : DbContext -{ - public DbSet ToDos { get; set; } - - public ToDoDbContext(DbContextOptions options) - : base(options) + public class Program { + public static async Task Main(string[] args) + { + WebApplicationBuilder? builder = WebApplication.CreateBuilder(args); + + // ConfigureServices + builder.Services.AddDbContext(options => + options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); + + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + + WebApplication app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseHttpsRedirection(); + + // Map endpoint to get ToDos + app.MapGet("/Todos", async (ToDoDbContext dbContext) => + { + return Results.Ok(await dbContext.ToDos.ToListAsync()); + }); + + // Map endpoint to get ToDo by id + app.MapGet("/Todos/{id}", async (ToDoDbContext dbContext, int id) => + { + ToDo? toDo = await dbContext.ToDos.FindAsync(id); + if (toDo is null) + { + return Results.NotFound(); + } + + return Results.Ok(toDo); + }); + + // Map endpoint to search ToDo by Title + app.MapGet("/Todos/Search", async (ToDoDbContext dbContext, string title) => + { + // Introduce a vulnerability for SQL Injection + // Ex: title = ';DROP TABLE dbo.ToDos;-- + + List? results = await dbContext.ToDos + .FromSqlRaw("SELECT * FROM dbo.ToDos WHERE Title = '" + title + "'") + .ToListAsync(); + + return Results.Ok(results); + }); + + // Map endpoint to create ToDo + app.MapPost("/Todos", async (ToDoDbContext dbContext, ToDo toDo) => + { + await dbContext.ToDos.AddAsync(toDo); + await dbContext.SaveChangesAsync(); + + return Results.Created($"/Todos/{toDo.Id}", toDo); + }); + + // Map endpoint to update ToDo + app.MapPut("/Todos/{id}", async (ToDoDbContext dbContext, int id, ToDo toDo) => + { + if (await dbContext.ToDos.FindAsync(id) == null) + { + return Results.NotFound(); + } + + toDo.Id = id; + dbContext.ToDos.Update(toDo); + + return Results.NoContent(); + }); + + // Map endpoint to delete ToDo + app.MapDelete("/Todos/{id}", async (ToDoDbContext dbContext, int id) => + { + ToDo? toDo = await dbContext.ToDos.FindAsync(id); + if (toDo is null) + { + return Results.NotFound(); + } + + dbContext.ToDos.Remove(toDo); + await dbContext.SaveChangesAsync(); + + return Results.NoContent(); + }); + + await app.RunAsync(); + } } } \ No newline at end of file diff --git a/Todo.Api/ToDoDbContext.cs b/Todo.Api/ToDoDbContext.cs new file mode 100644 index 0000000..bd59508 --- /dev/null +++ b/Todo.Api/ToDoDbContext.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore; +using Todo.Api.Models; + +namespace Todo.Api +{ + // Create ToDoDbContext with Entity Framework + public class ToDoDbContext : DbContext + { + public DbSet ToDos { get; set; } + + public ToDoDbContext(DbContextOptions options) + : base(options) + { + } + } +} \ No newline at end of file diff --git a/Todo.Api/Todo.Api.csproj b/Todo.Api/Todo.Api.csproj index 31e0eb0..c718bdb 100644 --- a/Todo.Api/Todo.Api.csproj +++ b/Todo.Api/Todo.Api.csproj @@ -3,7 +3,6 @@ net6.0 enable - enable