diff --git a/GdscBackend/Common/Extensions/ClaimsPrincipalExtensions.cs b/GdscBackend/Common/Extensions/ClaimsPrincipalExtensions.cs new file mode 100644 index 0000000..877cd8a --- /dev/null +++ b/GdscBackend/Common/Extensions/ClaimsPrincipalExtensions.cs @@ -0,0 +1,11 @@ +using System.Security.Claims; + +namespace GdscBackend.Common.Extensions; + +public static class ClaimsPrincipalExtensions +{ + public static string? GetUserId(this ClaimsPrincipal user) + { + return user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; + } +} diff --git a/GdscBackend/Database/IRepository.cs b/GdscBackend/Database/IRepository.cs index e2476a2..2adca32 100644 --- a/GdscBackend/Database/IRepository.cs +++ b/GdscBackend/Database/IRepository.cs @@ -8,10 +8,10 @@ public interface IRepository where T : class, IModel { DbSet DbSet { get; } Task AddAsync([NotNull] T entity); - Task GetAsync([NotNull] string id); + Task GetAsync([NotNull] string id); Task> GetAsync(); Task AddOrUpdateAsync([NotNull] T entity); - Task UpdateAsync([NotNull] string id ,[NotNull] object entity); - Task? DeleteAsync([NotNull] string id); + Task UpdateAsync([NotNull] string id ,[NotNull] object entity); + Task DeleteAsync([NotNull] string id); Task> DeleteAsync([NotNull] IEnumerable ids); } \ No newline at end of file diff --git a/GdscBackend/Database/Repository.cs b/GdscBackend/Database/Repository.cs index 98da45c..f961cdd 100644 --- a/GdscBackend/Database/Repository.cs +++ b/GdscBackend/Database/Repository.cs @@ -34,21 +34,21 @@ public async Task> GetAsync() return await DbSet.ToListAsync(); } - public async Task GetAsync([NotNull] string id) + public async Task GetAsync([NotNull] string id) { return await DbSet.FirstOrDefaultAsync(e => e.Id == id); } public async Task AddOrUpdateAsync([NotNull] T entity) { - if (entity is null) return null; + // if (entity is null) return null; var existing = await DbSet.FirstOrDefaultAsync(item => item.Id == entity.Id); - + return existing is null ? await AddAsync(entity) : await UpdateAsync(entity.Id, entity); } - public async Task UpdateAsync([NotNull] string id, [NotNull] object newEntity) + public async Task UpdateAsync([NotNull] string id, [NotNull] object newEntity) { var entity = await GetAsync(id); if (entity is null) return null; @@ -60,7 +60,7 @@ public async Task UpdateAsync([NotNull] string id, [NotNull] object newEntity return _dbSet.First(e => e.Id == id); } - public async Task? DeleteAsync([NotNull] string id) + public async Task DeleteAsync([NotNull] string id) { var entity = await DbSet.FirstOrDefaultAsync(item => item.Id == id); diff --git a/GdscBackend/Features/Articles/ArticleController.cs b/GdscBackend/Features/Articles/ArticleController.cs index 2929629..43ebeb0 100644 --- a/GdscBackend/Features/Articles/ArticleController.cs +++ b/GdscBackend/Features/Articles/ArticleController.cs @@ -1,4 +1,8 @@ -using GdscBackend.Database; +using System.Security.Claims; +using System.Xml.Linq; +using GdscBackend.Common.Extensions; +using GdscBackend.Database; +using GdscBackend.Utils; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -7,18 +11,17 @@ namespace GdscBackend.Features.Articles; [ApiController] [ApiVersion("1")] -[Authorize("CoreTeam")] +[Authorize(AuthorizeConstants.CoreTeam)] [Route("v1/Articles")] public class ArticleController : ControllerBase { - private readonly AppDbContext _dbContext; + private readonly IRepository _repo; - public ArticleController(AppDbContext appDbContext) + public ArticleController( IRepository repo ) { - _dbContext = appDbContext; + _repo = repo; } - - /* + [HttpPost] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -26,13 +29,12 @@ public ArticleController(AppDbContext appDbContext) public async Task> Post(ArticleRequest request) { - - //var author = await _dbContext.Users.FirstOrDefaultAsync(entity => entity.Id == request.AuthorId); - if (author is null) - { + var authorid = User.GetUserId(); + if (authorid is null) + { return NotFound("User not found!"); } - + var article = new ArticleModel { Id = Guid.NewGuid().ToString(), @@ -40,15 +42,14 @@ public async Task> Post(ArticleRequest request) Updated = DateTime.UtcNow, Title = request.Title, Content = request.Content, - //Author = author --> author from keycloak + AuthorId = authorid }; + + var result = await _repo.AddAsync(article); - var result = await _dbContext.Articles.AddAsync(article); - await _dbContext.SaveChangesAsync(); - - return Created("v1/Articles", result.Entity); + return Created("v1/Articles", result); } - */ + [HttpGet] [AllowAnonymous] @@ -56,15 +57,14 @@ public async Task> Post(ArticleRequest request) [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task>> Get() { - var result = _dbContext.Articles.Select( - article => new ArticleResponse - { - Id = article.Id, - Created = article.Created, - Title = article.Title, - Content = article.Content, - AuthorId = article.AuthorId - }).ToList(); + var result = await _repo.DbSet.Select(article => new ArticleResponse + { + Id = article.Id, + Created = article.Created, + Title = article.Title, + Content = article.Content, + AuthorId = article.AuthorId + }).ToListAsync(); return Ok(result); } @@ -76,12 +76,13 @@ public async Task>> Get() [ProducesResponseType(StatusCodes.Status401Unauthorized)] public async Task> Delete([FromRoute] string id) { - var articol = await _dbContext.Articles.FirstOrDefaultAsync(entity => entity.Id == id); + + var articol = await _repo.GetAsync(id); + if (articol is null) return NotFound("Article not found!"); + var result = await _repo.DeleteAsync(articol.Id); - var result = _dbContext.Articles.Remove(articol); - await _dbContext.SaveChangesAsync(); - return Ok(result.Entity); + return Ok(result); } @@ -90,29 +91,26 @@ public async Task> Delete([FromRoute] string id) [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task> ChangeAuthor([FromRoute] string id, [FromBody] string authorid) + public async Task> ChangeAuthor([FromRoute] string id) { - var article = await _dbContext.Articles.FirstOrDefaultAsync(entity => entity.Id == id); + var article = await _repo.GetAsync(id); if (article is null) return NotFound("Article not found!"); - /* check from keycloak - if (author is null) - { - return NotFound("Author not found!"); - } - */ + var authorid = User.GetUserId(); + if (authorid is null) return NotFound("Author not found!"); article.AuthorId = authorid; article.Updated = DateTime.UtcNow; - await _dbContext.SaveChangesAsync(); + await _repo.UpdateAsync(article.Id,article); + return Ok(new ArticleResponse { Id = article.Id, Created = article.Created, Title = article.Title, Content = article.Content, - AuthorId = article.AuthorId + AuthorId = article.AuthorId // from keycloak }); } @@ -123,12 +121,14 @@ public async Task> ChangeAuthor([FromRoute] string [ProducesResponseType(StatusCodes.Status401Unauthorized)] public async Task> ChangeContent([FromRoute] string id, [FromBody] string content) { - var article = await _dbContext.Articles.FirstOrDefaultAsync(entity => entity.Id == id); + var article = await _repo.GetAsync(id); if (article is null) return NotFound("Article not found!"); article.Content = content; article.Updated = DateTime.UtcNow; - await _dbContext.SaveChangesAsync(); + + await _repo.UpdateAsync(article.Id, article); + return Ok(new ArticleResponse { Id = article.Id, @@ -146,12 +146,15 @@ public async Task> ChangeContent([FromRoute] strin [ProducesResponseType(StatusCodes.Status401Unauthorized)] public async Task> ChangeTitle([FromRoute] string id, [FromBody] string title) { - var article = await _dbContext.Articles.FirstOrDefaultAsync(entity => entity.Id == id); + var article = await _repo.GetAsync(id); if (article is null) return NotFound("Article not found!"); article.Title = title; article.Updated = DateTime.UtcNow; - await _dbContext.SaveChangesAsync(); + + await _repo.UpdateAsync(article.Id, article); + + return Ok(new ArticleResponse { Id = article.Id, diff --git a/GdscBackend/Features/Articles/ArticleRequest.cs b/GdscBackend/Features/Articles/ArticleRequest.cs index bb14bfb..ab8464d 100644 --- a/GdscBackend/Features/Articles/ArticleRequest.cs +++ b/GdscBackend/Features/Articles/ArticleRequest.cs @@ -7,6 +7,4 @@ public class ArticleRequest [Required]public string Title { get; set; } public string Content { get; set; } - - [Required]public string AuthorId { get; set; } } \ No newline at end of file diff --git a/GdscBackend/Features/Events/EventsController.cs b/GdscBackend/Features/Events/EventsController.cs index 6375049..fd52133 100644 --- a/GdscBackend/Features/Events/EventsController.cs +++ b/GdscBackend/Features/Events/EventsController.cs @@ -43,7 +43,7 @@ public async Task> Post(EventRequest entity) [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> Delete([FromRoute] string id) + public async Task> Delete([FromRoute] string id) { var entity = await _repository.DeleteAsync(id); return entity is null ? NotFound() : Ok(entity); diff --git a/GdscBackend/GdscBackend.csproj b/GdscBackend/GdscBackend.csproj index cd0ce6e..893f2d2 100644 --- a/GdscBackend/GdscBackend.csproj +++ b/GdscBackend/GdscBackend.csproj @@ -28,7 +28,19 @@ - + + + + + + + + + + + + + diff --git a/GdscBackend/template.appsettings.Development.json b/GdscBackend/template.appsettings.Development.json deleted file mode 100644 index 0ccd4c0..0000000 --- a/GdscBackend/template.appsettings.Development.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Information" - } - }, - "ConnectionStrings": { - "Default": "Host=gdscupt.tech;Database=myDataBase;Username=guest;Password=myPassword;Port=6969;" - } -}