Skip to content

Commit

Permalink
Added API Authentication
Browse files Browse the repository at this point in the history
Added File Data Access
TODO : FTP Layer
  • Loading branch information
mazumdes committed Dec 1, 2021
1 parent a83e1b3 commit 088ff78
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 20 deletions.
43 changes: 43 additions & 0 deletions Library.Encyclopedia.API/Attributes/ApiKeyAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;

namespace Library.Encyclopedia.API.Attributes
{
[AttributeUsage(validOn: AttributeTargets.Class | AttributeTargets.Method)]
public class ApiKeyAttribute : Attribute, IAsyncActionFilter
{
private const string APIKEYNAME = "ApiKey";
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
if (!context.HttpContext.Request.Headers.TryGetValue(APIKEYNAME, out var extractedApiKey))
{
context.Result = new ContentResult()
{
StatusCode = 401,
Content = "Api Key was not provided"
};
return;
}

var appSettings = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();

var apiKey = appSettings.GetValue<string>(APIKEYNAME);

if (!apiKey.Equals(extractedApiKey))
{
context.Result = new ContentResult()
{
StatusCode = 401,
Content = "Api Key is not valid"
};
return;
}

await next();
}
}
}
33 changes: 32 additions & 1 deletion Library.Encyclopedia.API/Controllers/EncylopediaController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Library.Encyclopedia.DataAccess;
using Library.Encyclopedia.API.Attributes;
using Library.Encyclopedia.DataAccess;
using Library.Encyclopedia.DataAccess.DataAccess;
using Library.Encyclopedia.Entity.Interfaces;
using Library.Encyclopedia.Entity.Models;
Expand Down Expand Up @@ -166,6 +167,7 @@ public async Task<IActionResult> Get(Guid id)
/// </summary>
/// <returns></returns>
[HttpPost]
[ApiKey]
public async Task<IActionResult> Create([FromBody]Main model)
{
try
Expand Down Expand Up @@ -193,6 +195,7 @@ public async Task<IActionResult> Create([FromBody]Main model)
/// </summary>
/// <returns></returns>
[HttpPut("{id}")]
[ApiKey]
public async Task<IActionResult> Update(Guid id, [FromBody]MainUpdateModel model)
{
try
Expand All @@ -213,6 +216,7 @@ public async Task<IActionResult> Update(Guid id, [FromBody]MainUpdateModel model
/// </summary>
/// <returns></returns>
[HttpDelete("{id}")]
[ApiKey]
public async Task<IActionResult> Delete(Guid id)
{
try
Expand All @@ -227,5 +231,32 @@ public async Task<IActionResult> Delete(Guid id)
throw;
}
}

/// <summary>
/// Get all categories
/// </summary>
/// <returns></returns>
[HttpGet("fetchallcategories")]
public async Task<IActionResult> GetAllCategories()
{
try
{
var response = await mainDataAccess.GetAllCategoriesAsync();

if (response == null)
{
return StatusCode(204);
}
else
{
return Ok(response);
}
}
catch (Exception ex)
{
_logger.LogError(ex, $"an error has occured {ex.Message}");
throw;
}
}
}
}
59 changes: 59 additions & 0 deletions Library.Encyclopedia.API/Controllers/FilesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Library.Encyclopedia.API.Attributes;
using Library.Encyclopedia.DataAccess;
using Library.Encyclopedia.DataAccess.DataAccess;
using Library.Encyclopedia.Entity.Interfaces;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Library.Encyclopedia.API.Controllers
{
[ApiController]
[Route("[controller]")]
public class FilesController : ControllerBase
{
private readonly ILogger<FilesController> _logger;
private readonly IFilesDataAccess filesDataAccess;

public FilesController(ILogger<FilesController> logger, IApplicationDbContext dbContext)
{
_logger = logger;
this.filesDataAccess = new FilesDataAccess(dbContext);
}

/// <summary>
/// Upload Files
/// </summary>
/// <param name="query"></param>
/// <param name="offset"></param>
/// <param name="size"></param>
/// <param name="asc"></param>
/// <returns></returns>
//[HttpPost("{id}")]
//[ApiKey]
//public async Task<IActionResult> Get(Guid id, List<IFormFile> files)
//{
// try
// {
// ////var response = await filesDataAccess.AddFiles(id, files);

// //if (response == null)
// //{
// // return StatusCode(204);
// //}
// //else
// //{
// // return Ok(response);
// //}
// }
// catch (Exception ex)
// {
// _logger.LogError(ex, $"an error has occured {ex.Message}");
// throw;
// }
//}
}
}
1 change: 1 addition & 0 deletions Library.Encyclopedia.API/Library.Encyclopedia.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.21" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.5" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 0 additions & 2 deletions Library.Encyclopedia.API/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Library.Encyclopedia": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
Expand Down
2 changes: 1 addition & 1 deletion Library.Encyclopedia.API/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void ConfigureServices(IServiceCollection services)
configuration.RootPath = "ClientApp/dist";
});

services.AddScoped<IApplicationDbContext, ApplicationDbContext>();
services.AddScoped<IApplicationDbContext>(s => new ApplicationDbContext(Configuration.GetConnectionString("DefaultConnection")));
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down
5 changes: 3 additions & 2 deletions Library.Encyclopedia.API/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=FW-LIBR-LB430\\SQLEXPRESS;Database=Encyclopedia;Trusted_Connection=True;MultipleActiveResultSets=true"
}
"DefaultConnection": "Server=localhost\\SQLEXPRESS01;Database=Encyclopedia;Trusted_Connection=True;"
},
"ApiKey": "5929b003-8895-4fb3-bbb0-2eb101c48f66"
}
6 changes: 5 additions & 1 deletion Library.Encyclopedia.DataAccess/ApplicationDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ namespace Library.Encyclopedia.DataAccess
{
public class ApplicationDbContext : DbContext, IApplicationDbContext
{
private const string connectionString = "Server=localhost\\SQLEXPRESS01;Database=Encyclopedia;Trusted_Connection=True;";
private string connectionString;
public ApplicationDbContext(string connectionString)
{
this.connectionString = connectionString;
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
Expand Down
35 changes: 35 additions & 0 deletions Library.Encyclopedia.DataAccess/DataAccess/FilesDataAccess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Library.Encyclopedia.Entity.Interfaces;
using Library.Encyclopedia.Entity.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Library.Encyclopedia.DataAccess.DataAccess
{
public class FilesDataAccess : IFilesDataAccess
{
private IApplicationDbContext _dbcontext;
public FilesDataAccess(IApplicationDbContext dbcontext)
{
_dbcontext = dbcontext;
}

public async Task AddFiles(IEnumerable<Files> files)
{
await _dbcontext.Files.AddRangeAsync(files);
await _dbcontext.SaveChanges();
}

public async Task RemoveFiles(IEnumerable<Guid> ids)
{
//find file entities
var files = await _dbcontext.Files.Where(s => ids.Contains(s.Id)).ToListAsync();

_dbcontext.Files.RemoveRange(files);
await _dbcontext.SaveChanges();
}
}
}
45 changes: 32 additions & 13 deletions Library.Encyclopedia.DataAccess/DataAccess/MainDataAccess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public MainDataAccess(IApplicationDbContext dbcontext)
#region GET
async Task<MainMinimizedExternalCollection> IMainDataAccess.GetAsync(string query, int offset, int pagesize, bool ascending)
{
var temp = _dbcontext.Main.Where(s => s.Description.Contains(query) || s.Title.Contains(query))
query = query.ToLower();
var temp = _dbcontext.Main.Where(s => s.Description.ToLower().Contains(query) || s.Title.ToLower().Contains(query))
.Skip(offset)
.Take(pagesize);

Expand All @@ -36,7 +37,7 @@ async Task<MainMinimizedExternalCollection> IMainDataAccess.GetAsync(string quer
.ThenByDescending(s => s.Description)
.ToListAsync();

var total = await _dbcontext.Main.CountAsync(s => s.Description.Contains(query) || s.Title.Contains(query));
var total = await _dbcontext.Main.CountAsync(s => s.Description.ToLower().Contains(query) || s.Title.ToLower().Contains(query));

MainMinimizedExternalCollection result = new MainMinimizedExternalCollection(data.Minimize(), total);

Expand All @@ -45,21 +46,21 @@ async Task<MainMinimizedExternalCollection> IMainDataAccess.GetAsync(string quer

async Task<MainMinimizedExternalCollection> IMainDataAccess.GetByCategoryAsync(string category, int offset, int pagesize, bool ascending)
{
var temp = _dbcontext.Main.Where(s => s.Category.Equals(category, StringComparison.OrdinalIgnoreCase))
category = category.ToLower();
List<Main> rawData = await _dbcontext.Main.ToListAsync();
var temp = rawData.Where(s => s.Category.ToLower().Split(',', StringSplitOptions.None).Contains(category))
.Skip(offset)
.Take(pagesize);

IEnumerable<Main> data;
if (ascending)
data = await temp.OrderBy(s => s.Title)
.ThenBy(s => s.Description)
.ToListAsync();
data = temp.OrderBy(s => s.Title)
.ThenBy(s => s.Description);
else
data = await temp.OrderByDescending(s => s.Title)
.ThenByDescending(s => s.Description)
.ToListAsync();
data = temp.OrderByDescending(s => s.Title)
.ThenByDescending(s => s.Description);

var total = await _dbcontext.Main.CountAsync(s => s.Category.Equals(category, StringComparison.OrdinalIgnoreCase));
var total = rawData.Count(s => s.Category.ToLower().Split(',', StringSplitOptions.None).Contains(category));

MainMinimizedExternalCollection result = new MainMinimizedExternalCollection(data.Minimize(), total);

Expand All @@ -68,7 +69,8 @@ async Task<MainMinimizedExternalCollection> IMainDataAccess.GetByCategoryAsync(s

async Task<MainMinimizedExternalCollection> IMainDataAccess.GetByAlphabetAsync(char startingAlphabet, int offset, int pagesize, bool ascending)
{
var temp = _dbcontext.Main.Where(s => s.Title.StartsWith(startingAlphabet.ToString(), StringComparison.OrdinalIgnoreCase))
var alph = startingAlphabet.ToString().ToLower();
var temp = _dbcontext.Main.Where(s => s.Title.ToLower().StartsWith(alph))
.Skip(offset)
.Take(pagesize);

Expand All @@ -82,7 +84,7 @@ async Task<MainMinimizedExternalCollection> IMainDataAccess.GetByAlphabetAsync(c
.ThenByDescending(s => s.Description)
.ToListAsync();

var total = await _dbcontext.Main.CountAsync(s => s.Title.StartsWith(startingAlphabet.ToString(), StringComparison.OrdinalIgnoreCase));
var total = await _dbcontext.Main.CountAsync(s => s.Title.ToLower().StartsWith(alph));

MainMinimizedExternalCollection result = new MainMinimizedExternalCollection(data.Minimize(), total);

Expand All @@ -91,7 +93,7 @@ async Task<MainMinimizedExternalCollection> IMainDataAccess.GetByAlphabetAsync(c

async Task<Main> IMainDataAccess.GetAsync(Guid id)
{
return await _dbcontext.Main.FirstOrDefaultAsync(s => s.Id == id);
return await _dbcontext.Main.Include(s => s.Files).Include(s => s.Links).FirstOrDefaultAsync(s => s.Id == id);
}
#endregion

Expand Down Expand Up @@ -121,6 +123,7 @@ public async Task UpdateAsync(Guid id, MainUpdateModel model)
entry.Category = model.Category;

_dbcontext.Main.Update(entry);
await _dbcontext.SaveChanges();
}
else
throw new UpdateFailedException(UpdateFailErrorCode.EntryNotFound);
Expand All @@ -134,10 +137,26 @@ public async Task DeleteAsync(Guid id)
var entry = await _dbcontext.Main.FirstOrDefaultAsync(s => s.Id == id);

if (entry != null)
{
_dbcontext.Main.Remove(entry);
await _dbcontext.SaveChanges();
}
else
throw new DeleteFailedException(DeleteFailErrorCode.EntryNotFound);
}
#endregion

#region UTILS
public async Task<IEnumerable<string>> GetAllCategoriesAsync()
{
var data = await _dbcontext.Main.Select(s => s.Category).OrderBy(s => s).ToListAsync();
var result = new List<string>();
data.ForEach(item =>
{
result.AddRange(item.Split(','));
});
return result.Distinct();
}
#endregion
}
}
14 changes: 14 additions & 0 deletions Library.Encyclopedia.Entity/Interfaces/IFilesDataAccess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Library.Encyclopedia.Entity.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Library.Encyclopedia.Entity.Interfaces
{
public interface IFilesDataAccess
{
Task AddFiles(IEnumerable<Files> files);
Task RemoveFiles(IEnumerable<Guid> ids);
}
}
Loading

0 comments on commit 088ff78

Please sign in to comment.