Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions exercise.wwwapi/Endpoints/CommentEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Npgsql;
using System.Security.Claims;
using Post = exercise.wwwapi.Models.Post;

Expand Down Expand Up @@ -49,6 +50,7 @@ private static async Task<IResult> GetCommentsPerPost(IRepository<Comment> comme
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public static async Task<IResult> CreateComment(
CreateCommentRequestDTO request,
IRepository<Comment> commentRepository,
Expand All @@ -74,24 +76,31 @@ public static async Task<IResult> CreateComment(
return Results.BadRequest(failResponse);
}

var post = await postRepository.GetByIdAsync(postId);
if (post == null)
{
return Results.NotFound();
}

var comment = new Comment
{
PostId = postId,
UserId = userIdClaim.Value,
Body = request.Body,
CreatedAt = DateTime.UtcNow,
CreatedAt = DateTime.UtcNow
};

commentRepository.Insert(comment);
await commentRepository.SaveAsync();
try
{
await commentRepository.SaveAsync();
}
catch (DbUpdateException ex)
{
if (ex.InnerException is PostgresException CohortNumberEx &&
CohortNumberEx.SqlState == "23503") //23503 = FK violation (Post Id or User Id did not exist)
{
return TypedResults.NotFound($"Post with id: {postId} was not found");
}
}

var commentWithUser = await commentRepository.GetByIdWithIncludes(c => c.Include(c => c.User), comment.Id);

var commentData = new CommentDTO(comment);
var commentData = new CommentDTO(commentWithUser);

var response = new ResponseDTO<CommentDTO>
{
Expand All @@ -106,6 +115,7 @@ public static async Task<IResult> CreateComment(
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public static async Task<IResult> UpdateComment(
IRepository<Comment> commentRepository,
int id,
Expand Down Expand Up @@ -191,7 +201,7 @@ public static async Task<IResult> DeleteComment(
return TypedResults.NotFound();
}

if (comment.UserId != userIdClaim)
if (comment.UserId != userIdClaim && !claimsPrincipal.IsInRole("Teacher"))
{
return Results.Unauthorized();
}
Expand Down
46 changes: 25 additions & 21 deletions exercise.wwwapi/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
app.UseSwagger(c => c.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi2_0);

// Generate a JWT token using your existing signing key
var devJwtToken = GenerateDevJwtToken(token);
var devJwtToken = CreateToken(config);

app.UseSwaggerUI(c =>
{
Expand Down Expand Up @@ -220,31 +220,35 @@
app.ConfigureLikeEndpoints();
app.Run();

static string GenerateDevJwtToken(string signingKey)
static string CreateToken(IConfigurationSettings configurationSettings)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(signingKey);

var claims = new List<Claim>
{
new(ClaimTypes.Sid, "2"),
new(ClaimTypes.Name, "test2"),
new(ClaimTypes.Email, "test2@test2"),
new(ClaimTypes.Role, "Teacher")
};

var tokenKey = Environment.GetEnvironmentVariable(Globals.EnvironmentEnvVariable) == "Staging"
? Globals.TestTokenKey
: Globals.TokenKey;
var rawToken = configurationSettings.GetValue(tokenKey);
if (rawToken == null)
{
new Claim(ClaimTypes.Name, "Development User"),
new Claim(ClaimTypes.Email, "dev@localhost.com"),
new Claim(ClaimTypes.Role, "Teacher")
};

var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddDays(30),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature)
};
throw new Exception($"TokenKey: {tokenKey} could not be found.");
}

var jwtToken = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(jwtToken);
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(rawToken));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
var token = new JwtSecurityToken(
claims: claims,
expires: DateTime.MaxValue,
signingCredentials: credentials
);
var jwt = new JwtSecurityTokenHandler().WriteToken(token);
return jwt;
}

public partial class Program
{
} // needed for testing - please ignore
Expand Down