Skip to content

Commit

Permalink
Update authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
atrakic committed Oct 24, 2024
1 parent f85bcb2 commit a1b9ade
Show file tree
Hide file tree
Showing 19 changed files with 295 additions and 260 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ build:
dotnet restore
dotnet build --configuration Release --no-restore
dotnet test --no-restore --verbosity normal

test:
dotnet test

clean:
dotnet clean
4 changes: 2 additions & 2 deletions src/EchoApi/Auth/UserCredentials.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ namespace EchoApi.Auth;

public class UserCredentials
{
public string Username { get; set; }
public string Password { get; set; }
public string Username { get; set; } = default!;
public string Password { get; set; } = default!;
}
24 changes: 8 additions & 16 deletions src/EchoApi/Context/ApiDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,17 @@ public ApiDbContext(DbContextOptions<ApiDbContext> options) : base(options)
{
}

public DbSet<Message> Items { get; set; }
//public DbSet<UserCredentials> Users { get; set; }
public DbSet<Messages> Items { get; set; }

public async virtual Task<List<Message>> GetMessagesAsync()
public async virtual Task<List<Messages>> GetMessagesAsync()
{
return await Items
.OrderBy(message => message.CreatedAt)
.AsNoTracking()
.ToListAsync();
return await Items.ToListAsync();
}

// https://github.com/dotnet/AspNetCore.Docs.Samples/blob/main/test/integration-tests/8.x/IntegrationTestsSample/src/RazorPagesProject/Data/ApplicationDbContext.cs
// ...
public async virtual Task AddMessageAsync(Messages message)
{
await Items.AddAsync(message);
await SaveChangesAsync();
}
}

/*
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserCredentials>()
.HasNoKey();
} */
}
32 changes: 0 additions & 32 deletions src/EchoApi/Context/SeedData.cs

This file was deleted.

10 changes: 5 additions & 5 deletions src/EchoApi/DAL/IMessageRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ namespace EchoApi.DAL
{
public interface IMessageRepository
{
Message? GetItem(int id);
IEnumerable<Message> GetItems();
void AddItem(Message item);
void UpdateItem(Message item);
void RemoveItem(Message item);
Messages? GetItem(int id);
IEnumerable<Messages> GetItems();
void AddItem(Messages item);
void UpdateItem(Messages item);
void RemoveItem(Messages item);
void SaveChanges();
}
}
32 changes: 18 additions & 14 deletions src/EchoApi/DAL/MessageRepository.cs
Original file line number Diff line number Diff line change
@@ -1,56 +1,60 @@
using EchoApi.Model;
using EchoApi.Context;

using Microsoft.EntityFrameworkCore;
using System;

namespace EchoApi.DAL
{
public class MessageRepository : IMessageRepository
{
private readonly ApiDbContext context;
public MessageRepository(ApiDbContext context)
private readonly ILogger<MessageRepository> logger;

public MessageRepository(ApiDbContext context, ILogger<MessageRepository> logger)
{
this.context = context;
this.logger = logger;

if (context.Items.Any())
{
return;
}

var messageItems = new Message[]
logger.LogInformation("Seeding initial message items.");
var messageItems = new Messages[]
{
new Message { Name = "Item1" },
new Message { Name = "Item2" },
new Message { Name = "Item3" },
new Messages { Message = "Hello World from Echo Api" },
};

context.Items.AddRange(messageItems);
context.SaveChanges();
}

public void AddItem(Message item)
public void AddItem(Messages item)
{
logger.LogInformation("Adding a new message item.");
context.Items.Add(item);
context.SaveChanges();
}

public void UpdateItem(Message item)
public void UpdateItem(Messages item)
{
logger.LogInformation("Updating message item with ID {Id}.", item.Id);
context.Items.Update(item);
context.SaveChanges();
}

public Message? GetItem(int id)
public Messages? GetItem(int id)
{
logger.LogInformation("Retrieving message item with ID {Id}.", id);
return context.Items.FirstOrDefault(x => x.Id.Equals(id));
}

public IEnumerable<Message> GetItems()
public IEnumerable<Messages> GetItems()
{
return context.Items.ToList();
}

public void RemoveItem(Message item)
public void RemoveItem(Messages item)
{
logger.LogInformation("Removing message item with ID {Id}.", item.Id);
context.Items.Remove(item);
}

Expand Down
6 changes: 6 additions & 0 deletions src/EchoApi/Echo.API.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@Echo.OpenAPI_HostAddress = http://localhost:5000

GET {{Echo.OpenAPI_HostAddress}}/message/
Accept: application/json

###
9 changes: 1 addition & 8 deletions src/EchoApi/EchoApi.csproj
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>25e57428-8ef1-40a9-b9e3-41d95a73b652</UserSecretsId>
<RootNamespace>EchoApi</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.RateLimiting" Version="7.0.0-rc.2.22476.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.6">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="NSwag.AspNetCore" Version="14.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>

</Project>
106 changes: 106 additions & 0 deletions src/EchoApi/EndpointMappings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using EchoApi.Auth;
using EchoApi.DAL;
using EchoApi.Model;
using EchoApi.Services;

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

namespace EchoApi;

public static class EndpointMappings
{
public static void MapEchoApiV1(this IEndpointRouteBuilder group)
{
group.MapGet("/healthz", () => Results.Ok());
group.MapPost("/token", (TokenService tokenService, [FromBody] UserCredentials credentials) =>
{
bool isValidUser = AuthenticateUser(credentials);

if (isValidUser)
{
var token = tokenService.GenerateToken(credentials.Username);
return Results.Ok(new { token });
}
else
{
return Results.Unauthorized();
}
});

group.MapGet("/api/messages", GetAllMessages);
group.MapGet("/api/message/{id:int}", GetMessageById).WithOpenApi();
group.MapPost("/", CreateMessage).RequireAuthorization().WithOpenApi();
group.MapPut("/api/message/{id}", UpdateMessage).RequireAuthorization().WithOpenApi();
group.MapDelete("/api/message/{id}", DeleteMessage).RequireAuthorization().WithOpenApi();
}

private static IResult GetAllMessages(IMessageRepository msgRepository)
{
int MAX_MESSAGE_ITEMS = 10;
return TypedResults.Ok(msgRepository.GetItems().Take(MAX_MESSAGE_ITEMS));
}

private static IResult GetMessageById(int id, IMessageRepository msgRepository)
{
var item = msgRepository.GetItem(id);
return item != null ? TypedResults.Ok(item) : TypedResults.NotFound();
}

private static IResult CreateMessage(Messages item, IMessageRepository msgRepository)
{
msgRepository.AddItem(item);
msgRepository.SaveChanges();
return Results.Created($"/api/message/{item.Id}", item);
}

private static IResult UpdateMessage(int id, Messages msgItem, IMessageRepository msgRepository)
{
var existingItem = msgRepository.GetItem(id);

if (existingItem is null)
{
return TypedResults.NotFound();
}

existingItem.Message = msgItem.Message;

msgRepository.UpdateItem(existingItem);
msgRepository.SaveChanges();
return TypedResults.NoContent();
}

private static IResult DeleteMessage(int id, IMessageRepository msgRepository)
{
var existingItem = msgRepository.GetItem(id);

if (existingItem is null)
{
return TypedResults.NotFound();
}

msgRepository.RemoveItem(existingItem);
msgRepository.SaveChanges();
return TypedResults.NoContent();
}

/// <summary>
/// Authenticates the user.
/// </summary>
/// <param name="credentials">The user credentials to authenticate.</param>
/// <returns>True if the user is authenticated, otherwise false.</returns>
private static bool AuthenticateUser(UserCredentials credentials)
{
var USERNAME = Environment.GetEnvironmentVariable("USERNAME") ?? "admin"; //builder.Configuration["AppSettings:Authentication:Username"];
var PASSWORD = Environment.GetEnvironmentVariable("PASSWORD") ?? "admin123"; //builder.Configuration["AppSettings:Authentication:Password"];

if (credentials.Username != USERNAME || credentials.Password != PASSWORD)
{
return false;
}
return true;
}
}
9 changes: 0 additions & 9 deletions src/EchoApi/Model/Message.cs

This file was deleted.

9 changes: 9 additions & 0 deletions src/EchoApi/Model/Messages.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace EchoApi.Model
{
public class Messages
{
public int Id { get; private set; }
public long UpdatedAt { get; private set; } = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
public required string Message { get; set; }
}
}
Loading

0 comments on commit a1b9ade

Please sign in to comment.