-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(users): implement demo RESTful API (#1)
- Loading branch information
Showing
20 changed files
with
1,571 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,12 @@ | |
"commands": [ | ||
"husky" | ||
] | ||
}, | ||
"dotnet-ef": { | ||
"version": "6.0.12", | ||
"commands": [ | ||
"dotnet-ef" | ||
] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
POSTGRES_USER=test | ||
POSTGRES_PASSWORD=test | ||
BRIGHT_HOSTNAME=app.neuralegion.com | ||
BRIGHT_TOKEN= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -383,6 +383,7 @@ autom4te.cache/ | |
*.tar.gz | ||
tarballs/ | ||
test-results/ | ||
.env | ||
|
||
# Mac bundle stuff | ||
*.dmg | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
version: '3' | ||
|
||
services: | ||
postgres: | ||
image: postgres:14-alpine | ||
restart: always | ||
command: postgres -c fsync=off -c synchronous_commit=off -c full_page_writes=off -c random_page_cost=1.0 | ||
environment: | ||
POSTGRES_DB: test | ||
POSTGRES_PASSWORD: '${POSTGRES_PASSWORD:-test}' | ||
POSTGRES_USER: '${POSTGRES_USER:-test}' | ||
ports: | ||
- '5432:5432' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> | ||
<UserSecretsId>45122f4e-e577-4e10-91ba-2b2de7cd77a3</UserSecretsId> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="DotNetEnv" Version="2.3.0" /> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.12" /> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.12"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.7" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="..\..\.dockerignore"> | ||
<Link>.dockerignore</Link> | ||
</Content> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.Net; | ||
using App.Models; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace App.Controllers; | ||
|
||
[ApiController] | ||
[Route("[controller]")] | ||
public class UsersController : ControllerBase | ||
{ | ||
private readonly Users _users; | ||
|
||
public UsersController(Users users) | ||
{ | ||
_users = users; | ||
} | ||
|
||
[HttpPost] | ||
[ProducesResponseType(typeof(User), (int)HttpStatusCode.Created)] | ||
public Task<User> Create([FromBody] CreateUserDto createUserDto) => _users.Create(createUserDto); | ||
|
||
[HttpGet] | ||
[ProducesResponseType(typeof(IEnumerable<User>), (int)HttpStatusCode.OK)] | ||
public Task<List<User>> FindByName([FromQuery] string name) => _users.FindByName(name); | ||
|
||
[HttpGet] | ||
[Route("{id}")] | ||
[ProducesResponseType(typeof(User), (int)HttpStatusCode.OK)] | ||
public Task<User?> FindOne(int id) => _users.FindOne(id); | ||
|
||
[HttpDelete] | ||
[Route("{id}")] | ||
[ProducesResponseType((int)HttpStatusCode.NoContent)] | ||
public Task Remove(int id) => _users.Remove(id); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base | ||
WORKDIR /app | ||
EXPOSE 80 | ||
EXPOSE 443 | ||
|
||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build | ||
WORKDIR /src | ||
COPY ["src/App/App.csproj", "src/App/"] | ||
RUN dotnet restore "src/App/App.csproj" | ||
COPY . . | ||
WORKDIR "/src/src/App" | ||
RUN dotnet build "App.csproj" -c Release -o /app/build | ||
|
||
FROM build AS publish | ||
RUN dotnet publish "App.csproj" -c Release -o /app/publish | ||
|
||
FROM base AS final | ||
WORKDIR /app | ||
COPY --from=publish /app/publish . | ||
ENTRYPOINT ["dotnet", "App.dll"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using App.Models; | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
namespace App.Infrastructure; | ||
|
||
public class UserContext : DbContext | ||
{ | ||
public UserContext(DbContextOptions<UserContext> options) : base(options) | ||
{ | ||
} | ||
|
||
public DbSet<User> Users { get; set; } | ||
|
||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => | ||
optionsBuilder.UseNpgsql( | ||
$"Host=localhost;Username={Environment.GetEnvironmentVariable("POSTGRES_USER")};Password={Environment.GetEnvironmentVariable("POSTGRES_PASSWORD")};Database=test"); | ||
|
||
protected override void OnModelCreating(ModelBuilder modelBuilder) | ||
{ | ||
modelBuilder.Entity<User>() | ||
.Property(u => u.Name) | ||
.IsRequired(); | ||
|
||
modelBuilder.Entity<User>() | ||
.Property(u => u.IsActive) | ||
.HasDefaultValue(true); | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
src/App/Migrations/20221214233020_InitialCreate.Designer.cs
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using Microsoft.EntityFrameworkCore.Migrations; | ||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; | ||
|
||
#nullable disable | ||
|
||
namespace App.Migrations; | ||
|
||
public partial class InitialCreate : Migration | ||
{ | ||
protected override void Up(MigrationBuilder migrationBuilder) | ||
{ | ||
migrationBuilder.CreateTable( | ||
name: "Users", | ||
columns: table => new | ||
{ | ||
Id = table.Column<int>(type: "integer", nullable: false) | ||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), | ||
Name = table.Column<string>(type: "text", nullable: false), | ||
IsActive = table.Column<bool>(type: "boolean", nullable: false, defaultValue: true) | ||
}, | ||
constraints: table => | ||
{ | ||
table.PrimaryKey("PK_Users", x => x.Id); | ||
}); | ||
} | ||
|
||
protected override void Down(MigrationBuilder migrationBuilder) | ||
{ | ||
migrationBuilder.DropTable( | ||
name: "Users"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// <auto-generated /> | ||
using App.Infrastructure; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.EntityFrameworkCore.Infrastructure; | ||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | ||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; | ||
|
||
#nullable disable | ||
|
||
namespace App.Migrations; | ||
|
||
[DbContext(typeof(UserContext))] | ||
partial class UserContextModelSnapshot : ModelSnapshot | ||
{ | ||
protected override void BuildModel(ModelBuilder modelBuilder) | ||
{ | ||
#pragma warning disable 612, 618 | ||
modelBuilder | ||
.HasAnnotation("ProductVersion", "6.0.12") | ||
.HasAnnotation("Relational:MaxIdentifierLength", 63); | ||
|
||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); | ||
|
||
modelBuilder.Entity("App.Models.User", b => | ||
{ | ||
b.Property<int>("Id") | ||
.ValueGeneratedOnAdd() | ||
.HasColumnType("integer"); | ||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id")); | ||
b.Property<bool>("IsActive") | ||
.ValueGeneratedOnAdd() | ||
.HasColumnType("boolean") | ||
.HasDefaultValue(true); | ||
b.Property<string>("Name") | ||
.IsRequired() | ||
.HasColumnType("text"); | ||
b.HasKey("Id"); | ||
b.ToTable("Users"); | ||
}); | ||
#pragma warning restore 612, 618 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace App.Models; | ||
|
||
public class CreateUserDto | ||
{ | ||
public string Name { get; init; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace App.Models; | ||
|
||
public class User | ||
{ | ||
public int Id { get; set; } | ||
|
||
public string Name { get; set; } | ||
|
||
public bool IsActive { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
using App.Infrastructure; | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
namespace App.Models; | ||
|
||
public class Users | ||
{ | ||
private readonly UserContext _userContext; | ||
|
||
public Users(UserContext userContext) | ||
{ | ||
_userContext = userContext; | ||
} | ||
|
||
public async Task<User> Create(CreateUserDto payload) | ||
{ | ||
var user = new User | ||
{ | ||
Name = payload.Name | ||
}; | ||
|
||
_userContext.Users.Add(user); | ||
|
||
await _userContext.SaveChangesAsync().ConfigureAwait(false); | ||
|
||
return user; | ||
} | ||
|
||
public Task<User?> FindOne(int id) => _userContext.Users.FindAsync(id).AsTask(); | ||
|
||
public async Task Remove(int id) | ||
{ | ||
var user = _userContext.Users.SingleOrDefault(x => x.Id == id); | ||
|
||
if (user is not null) | ||
{ | ||
_userContext.Users.Remove(user); | ||
await _userContext.SaveChangesAsync().ConfigureAwait(false); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// This method performs a simple SQL query that would typically search through the users table and retrieve | ||
/// the user who has a concrete ID. However, an attacker can easily use the lack of validation from | ||
/// user inputs to read sensitive data from the database, modify database data, or | ||
/// execute administration operations by inputting values that the developer did not consider a valid (e.g. `1 OR 2028=2028` or `1; DROP user--`) | ||
/// | ||
/// Using the built-in `Where` method that escapes the input passed to it automatically before it is inserted into the query, | ||
/// you can fix the actual issue: | ||
/// ```csharp | ||
/// public Task<List<User>> FindByName(string name) | ||
/// { | ||
/// return _userContext.Users.Where(u => u.Name.Contains(name)).ToListAsync(); | ||
/// } | ||
/// </summary> | ||
public Task<List<User>> FindByName(string name) | ||
{ | ||
var query = $@"select * from ""Users"" where ""Name"" ilike '{name}%'"; | ||
|
||
return _userContext.Users.FromSqlRaw(query).ToListAsync(); | ||
} | ||
} |
Oops, something went wrong.