diff --git a/Library.Encyclopedia.API/Attributes/ApiKeyAttribute.cs b/Library.Encyclopedia.API/Attributes/ApiKeyAttribute.cs
index 924a61a..a3ee159 100644
--- a/Library.Encyclopedia.API/Attributes/ApiKeyAttribute.cs
+++ b/Library.Encyclopedia.API/Attributes/ApiKeyAttribute.cs
@@ -7,6 +7,10 @@
namespace Library.Encyclopedia.API.Attributes
{
+ ///
+ /// This is a custom attribute for API Kay validation
+ /// Extracts API key from the header and then checks it with the API KEY hardcoded in appsettings
+ ///
[AttributeUsage(validOn: AttributeTargets.Class | AttributeTargets.Method)]
public class ApiKeyAttribute : Attribute, IAsyncActionFilter
{
diff --git a/Library.Encyclopedia.API/Controllers/EncylopediaController.cs b/Library.Encyclopedia.API/Controllers/EncylopediaController.cs
index 68b3d27..023d81a 100644
--- a/Library.Encyclopedia.API/Controllers/EncylopediaController.cs
+++ b/Library.Encyclopedia.API/Controllers/EncylopediaController.cs
@@ -14,26 +14,37 @@
namespace Library.Encyclopedia.Controllers
{
///
- /// CRUD operations on Main Table
+ /// Controller to perform CRUD operations on Main Table
///
[ApiController]
[Route("[controller]")]
public class EncylopediaController : ControllerBase
{
+ #region PRIVATE FIELDS
private readonly ILogger _logger;
private readonly IMainDataAccess mainDataAccess;
+ #endregion
+ #region CONSTRUCTOR
///
- /// Constructor
+ /// Contructor for EncylopediaController
///
- ///
- ///
+ /// logger instance
+ /// db instance
+ /// appsettings configuration
+ /// file upload/download/delete layer
public EncylopediaController(ILogger logger, IApplicationDbContext dbContext, IConfiguration configuration, IFilesAdapter filesAdapter)
{
_logger = logger;
this.mainDataAccess = new MainDataAccess(dbContext, configuration, filesAdapter);
- }
+ }
+ #endregion
+ #region LOGIN
+ ///
+ /// Login to perform POST/PUT/DELETE operations on the database
+ ///
+ ///
[HttpGet("Login")]
[Authorize(Roles = @"EncyclopediaAdministrators")]
public IActionResult Login()
@@ -53,7 +64,9 @@ public IActionResult Login()
throw;
}
}
+ #endregion
+ #region GET
///
/// Get all items based on search query
///
@@ -185,21 +198,19 @@ public async Task Get(Guid id)
}
///
- /// Create new entry
+ /// Get all categories
///
///
- [HttpPost]
- //[ApiKey]
- [Authorize(Roles = @"EncyclopediaAdministrators")]
- public async Task Create([FromBody]Main model)
+ [HttpGet("fetchallcategories")]
+ public async Task GetAllCategories()
{
try
{
- var response = await mainDataAccess.CreateAsync(model);
+ var response = await mainDataAccess.GetAllCategoriesAsync();
if (response == null)
{
- return StatusCode(500);
+ return StatusCode(204);
}
else
{
@@ -212,19 +223,21 @@ public async Task Create([FromBody]Main model)
throw;
}
}
+ #endregion
+ #region POST
///
/// Create new entry
///
///
- [HttpPut("{id}")]
+ [HttpPost]
//[ApiKey]
[Authorize(Roles = @"EncyclopediaAdministrators")]
- public async Task Update(Guid id, [FromBody]MainUpdateModel model)
+ public async Task Create([FromBody]Main model)
{
try
{
- var response = await mainDataAccess.UpdateAsync(id, model);
+ var response = await mainDataAccess.CreateAsync(model);
if (response == null)
{
@@ -241,21 +254,30 @@ public async Task Update(Guid id, [FromBody]MainUpdateModel model
throw;
}
}
+ #endregion
+ #region PUT
///
/// Create new entry
///
///
- [HttpDelete("{id}")]
+ [HttpPut("{id}")]
//[ApiKey]
[Authorize(Roles = @"EncyclopediaAdministrators")]
- public async Task Delete(Guid id)
+ public async Task Update(Guid id, [FromBody]MainUpdateModel model)
{
try
{
- await mainDataAccess.DeleteAsync(id);
+ var response = await mainDataAccess.UpdateAsync(id, model);
- return Ok();
+ if (response == null)
+ {
+ return StatusCode(500);
+ }
+ else
+ {
+ return Ok(response);
+ }
}
catch (Exception ex)
{
@@ -263,32 +285,30 @@ public async Task Delete(Guid id)
throw;
}
}
+ #endregion
+ #region DELETE
///
- /// Get all categories
+ /// Create new entry
///
///
- [HttpGet("fetchallcategories")]
- public async Task GetAllCategories()
+ [HttpDelete("{id}")]
+ //[ApiKey]
+ [Authorize(Roles = @"EncyclopediaAdministrators")]
+ public async Task Delete(Guid id)
{
try
{
- var response = await mainDataAccess.GetAllCategoriesAsync();
+ await mainDataAccess.DeleteAsync(id);
- if (response == null)
- {
- return StatusCode(204);
- }
- else
- {
- return Ok(response);
- }
+ return Ok();
}
catch (Exception ex)
{
_logger.LogError(ex, $"an error has occured {ex.Message}");
throw;
}
- }
+ }
+ #endregion
}
}
\ No newline at end of file
diff --git a/Library.Encyclopedia.API/Controllers/FilesController.cs b/Library.Encyclopedia.API/Controllers/FilesController.cs
index acfcb17..83c2610 100644
--- a/Library.Encyclopedia.API/Controllers/FilesController.cs
+++ b/Library.Encyclopedia.API/Controllers/FilesController.cs
@@ -6,6 +6,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@@ -21,12 +22,14 @@ public class FilesController : ControllerBase
{
private readonly ILogger _logger;
private readonly IFilesAdapter filesAdapter;
+ private readonly IConfiguration configuration;
private readonly IFilesDataAccess filesDataAccess;
- public FilesController(ILogger logger, IApplicationDbContext dbContext, IFilesAdapter filesAdapter)
+ public FilesController(ILogger logger, IApplicationDbContext dbContext, IFilesAdapter filesAdapter, IConfiguration configuration)
{
_logger = logger;
this.filesAdapter = filesAdapter;
+ this.configuration = configuration;
this.filesDataAccess = new FilesDataAccess(dbContext);
}
@@ -77,7 +80,7 @@ public async Task Post(Guid id, IFormFile file, string descriptio
}
///
- /// Upload Files
+ /// Download Files
///
///
///
@@ -100,6 +103,55 @@ public IActionResult Get(string id, string name, string contentType)
}
}
+ ///
+ /// Create Viewable link
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("CreateViewableLink/{id}")]
+ [Authorize(Roles = @"EncyclopediaAdministrators")]
+ public IActionResult CreateViewableLink(string id, string name)
+ {
+ try
+ {
+ this.filesAdapter.CreateViewableLink(id, name);
+ var baseUrl = configuration.GetSection("TempAssetsBaseUrl").Value;
+ return Ok(baseUrl + '/' + id + '/' + name);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"an error has occured {ex.Message}");
+ throw;
+ }
+ }
+
+ ///
+ /// Destroy Viewable link
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpDelete("DestroyViewableLink/{id}")]
+ [Authorize(Roles = @"EncyclopediaAdministrators")]
+ public IActionResult DestroyViewableLink(string id, string name)
+ {
+ try
+ {
+ this.filesAdapter.DestroyViewableLink(id, name);
+ return Ok();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"an error has occured {ex.Message}");
+ throw;
+ }
+ }
+
///
/// Delete File
///
diff --git a/Library.Encyclopedia.API/Startup.cs b/Library.Encyclopedia.API/Startup.cs
index c90cbf6..a87594b 100644
--- a/Library.Encyclopedia.API/Startup.cs
+++ b/Library.Encyclopedia.API/Startup.cs
@@ -46,24 +46,26 @@ public void ConfigureServices(IServiceCollection services)
string userName = Configuration.GetValue("FileAdapterSettings:username");
string password = Configuration.GetValue("FileAdapterSettings:password");
string basePath = Configuration.GetValue("FileAdapterSettings:basePath");
+ string tempAssetsFilePath = Configuration.GetValue("TempAssetsLocation");
services.AddSingleton(s =>
{
- return new LinuxFileSaveAdapter(url, userName, password, basePath);
+ return new LinuxFileSaveAdapter(url, userName, password, basePath, tempAssetsFilePath);
});
}
- else if(Configuration.GetValue("FileAdapterSettings:type").Equals("windows", System.StringComparison.OrdinalIgnoreCase))
+ else if (Configuration.GetValue("FileAdapterSettings:type").Equals("windows", System.StringComparison.OrdinalIgnoreCase))
{
string filePath = Configuration.GetValue("FileAdapterSettings:filePath");
+ string tempAssetsFilePath = Configuration.GetValue("TempAssetsLocation");
services.AddSingleton(s =>
{
- return new WindowsFileSaveAdapter(filePath);
+ return new WindowsFileSaveAdapter(filePath, tempAssetsFilePath);
});
}
services.AddScoped(s => new ApplicationDbContext(Configuration.GetConnectionString("DefaultConnection")));
-
+
services.Configure(x =>
{
x.ValueLengthLimit = int.MaxValue;
diff --git a/Library.Encyclopedia.API/appsettings.json b/Library.Encyclopedia.API/appsettings.json
index 50bf267..bfac7f4 100644
--- a/Library.Encyclopedia.API/appsettings.json
+++ b/Library.Encyclopedia.API/appsettings.json
@@ -14,17 +14,19 @@
"DefaultConnection": "Server=localhost;Database=Encyclopedia;User=root;Password=RW_qh+-ta5hW*2s"
},
"ApiKey": "5929b003-8895-4fb3-bbb0-2eb101c48f66",
+ "TempAssetsBaseUrl": "https://tools.library.pfw.edu/encyclopedia/pfwencyclopediaassets",
+ "TempAssetsLocation": "C:\\inetpub\\wwwroot\\pfwencyclopediaassets",
"FileAdapterSettings": {
// linux or windows
- "type": "linux",
+ "type": "windows",
// For Linux
- "url": "10.161.100.82",
- "username": "serviceuser",
- "password": "P!ssword+007",
- "basePath": "Applications/PFW Encyclopedia Files"
+ //"url": "10.161.100.82",
+ //"username": "serviceuser",
+ //"password": "P!ssword+007",
+ //"basePath": "Applications/PFW Encyclopedia Files"
// For Windows
- //"filePath": "C:\\inetpub\\wwwroot\\PFW Encyclopedia Files\\"
+ "filePath": "C:\\inetpub\\wwwroot\\PFW Encyclopedia Files\\"
}
}
\ No newline at end of file
diff --git a/Library.Encyclopedia.DataAccess/FileAccess/LinuxFileSaveAdapter.cs b/Library.Encyclopedia.DataAccess/FileAccess/LinuxFileSaveAdapter.cs
index b1b3222..7eddfd7 100644
--- a/Library.Encyclopedia.DataAccess/FileAccess/LinuxFileSaveAdapter.cs
+++ b/Library.Encyclopedia.DataAccess/FileAccess/LinuxFileSaveAdapter.cs
@@ -14,19 +14,33 @@ public class LinuxFileSaveAdapter : IFilesAdapter, IDisposable
{
private readonly string url;
private readonly string basePath;
+ private readonly string tempAssetsFilePath;
private readonly NetworkCredential networkCredential;
private SftpClient client;
- public LinuxFileSaveAdapter(string url, string userName, string password, string basePath)
+ public LinuxFileSaveAdapter(string url, string userName, string password, string basePath, string tempAssetsFilePath)
{
this.url = url;
this.basePath = basePath;
+ this.tempAssetsFilePath = tempAssetsFilePath;
this.networkCredential = new NetworkCredential(userName, password);
client = new SftpClient(url, 22, networkCredential.UserName, networkCredential.Password);
client.Connect();
}
+ public void CreateViewableLink(string id, string name)
+ {
+ if (!Directory.Exists(Path.Combine(tempAssetsFilePath, id)))
+ Directory.CreateDirectory(Path.Combine(tempAssetsFilePath, id));
+
+ var remotePath = $@"/home/{networkCredential.UserName}/" + basePath + '/' + id.ToString() + '/' + name;
+ using (Stream fileStream = File.Create(Path.Combine(tempAssetsFilePath, id, name)))
+ {
+ client.DownloadFile(remotePath, fileStream);
+ }
+ }
+
public void DeleteFile(string id, string name)
{
var completeUrl = $@"/home/{networkCredential.UserName}/" + basePath + '/' + id.ToString() + '/' + name;
@@ -47,7 +61,7 @@ public void DeleteFiles(string id)
{
if (file.Name != "." && file.Name != "..")
{
- client.DeleteFile(file.FullName);
+ client.DeleteFile(file.FullName);
}
}
@@ -55,6 +69,11 @@ public void DeleteFiles(string id)
}
}
+ public void DestroyViewableLink(string id, string name)
+ {
+ File.Delete(Path.Combine(tempAssetsFilePath, id, name));
+ }
+
public void Dispose()
{
this.client.Disconnect();
diff --git a/Library.Encyclopedia.DataAccess/FileAccess/WindowsFileSaveAdapter.cs b/Library.Encyclopedia.DataAccess/FileAccess/WindowsFileSaveAdapter.cs
index c2ae715..7ac6be8 100644
--- a/Library.Encyclopedia.DataAccess/FileAccess/WindowsFileSaveAdapter.cs
+++ b/Library.Encyclopedia.DataAccess/FileAccess/WindowsFileSaveAdapter.cs
@@ -13,10 +13,20 @@ namespace Library.Encyclopedia.DataAccess.FileAccess
public class WindowsFileSaveAdapter : IFilesAdapter
{
private readonly string networkPath;
+ private readonly string tempAssetFileLocation;
- public WindowsFileSaveAdapter(string networkPath)
+ public WindowsFileSaveAdapter(string networkPath, string tempAssetFileLocation)
{
this.networkPath = networkPath;
+ this.tempAssetFileLocation = tempAssetFileLocation;
+ }
+
+ public void CreateViewableLink(string id, string name)
+ {
+ if (!Directory.Exists(Path.Combine(tempAssetFileLocation, id)))
+ Directory.CreateDirectory(Path.Combine(tempAssetFileLocation, id));
+
+ File.Copy(Path.Combine(networkPath, id, name), Path.Combine(tempAssetFileLocation, id, name));
}
public void DeleteFile(string id, string name)
@@ -33,6 +43,11 @@ public void DeleteFiles(string id)
Directory.Delete(Path.Combine(networkPath, id));
}
+ public void DestroyViewableLink(string id, string name)
+ {
+ File.Delete(Path.Combine(tempAssetFileLocation, id, name));
+ }
+
public Stream DownloadFile(string id, string name)
{
return File.OpenRead(Path.Combine(networkPath, id, name));
@@ -59,7 +74,7 @@ public async Task UploadFile(Guid id, IFormFile file)
return true;
}
- catch (Exception ex)
+ catch (Exception)
{
return false;
}
diff --git a/Library.Encyclopedia.Entity/Interfaces/IFilesAdapter.cs b/Library.Encyclopedia.Entity/Interfaces/IFilesAdapter.cs
index e65813a..afbc621 100644
--- a/Library.Encyclopedia.Entity/Interfaces/IFilesAdapter.cs
+++ b/Library.Encyclopedia.Entity/Interfaces/IFilesAdapter.cs
@@ -13,5 +13,8 @@ public interface IFilesAdapter
Stream DownloadFile(string id, string name);
public void DeleteFiles(string id);
public void DeleteFile(string id, string name);
+
+ public void CreateViewableLink(string id, string name);
+ public void DestroyViewableLink(string id, string name);
}
}
\ No newline at end of file