Skip to content
Open
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
/PTransfer/keys
/PTransfer-Tests/bin/Debug/netcoreapp3.1
/PTransfer-Tests/obj
/Base64Data.txt
/TestImage.jpg
3 changes: 1 addition & 2 deletions DB/StoredProcedures/sp_GetUploadRequestParts.sql
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ begin
inner join tbl_user_master u
on r.file_owner = u.id
where r.id = parRequestId
and r.is_active = 1
order by p.part_number;
and r.is_active = 1;
end;
6 changes: 3 additions & 3 deletions DB/Tables/sp_tbl_upload_request_parts.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ begin
create table tbl_upload_request_parts
(
id int primary key auto_increment,
request_id int not null,
part_value text not null,
request_id int not null,
part_value longtext not null,
is_active tinyint default 1,
created_by int not null,
created_by int not null,
created timestamp default current_timestamp,
modified_by int default null,
modified timestamp default null
Expand Down
1 change: 1 addition & 0 deletions PTransfer/Base-Data.txt

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions PTransfer/Controllers/RequestController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using PTransfer.Core;
using PTransfer.RequestModels;
using PTransfer.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace PTransfer.Controllers {
[ApiController]
[Route("/upload-request")]
[Produces("application/json")]
public class RequestController : ControllerBase {
[HttpPost]
public IActionResult CreateRequest([FromBody] UploadRequestCreate uploadRequestCreate) {
Response response;
if (!ModelState.IsValid) {
return BadRequest(ModelState);
}
string token = this.HttpContext.Request.Headers[Constants.JW_TOKEN_KEY];
var decodedToken = JwTHelper.ValidateJwT(token);
dynamic tokenData = JObject.Parse(decodedToken);
if (string.IsNullOrEmpty(decodedToken) || (int)tokenData.UserId <= 0) {
response = new Response(Constants.FORBIDDEN_MSG, Constants.ERROR_MSG, null);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return new ObjectResult(response);
}
int requestId = UploadRequestHelper.CreateRequest(uploadRequestCreate, (int)tokenData.UserId);
response = new Response(Constants.SUCCESS_MSG, Constants.SUCCESS_MSG, requestId);
HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
return new ObjectResult(response);
}
[HttpPut]
public IActionResult UpdateRequest([FromBody] UploadRequestUpdate uploadRequestUpdate) {
Response response;
if (!ModelState.IsValid) {
return BadRequest(ModelState);
}
string token = HttpContext.Request.Headers[Constants.JW_TOKEN_KEY];
if (string.IsNullOrEmpty(token)) {
response = new Response(Constants.FORBIDDEN_MSG, Constants.ERROR_MSG, null);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return new ObjectResult(response);
}
var decodedToken = JwTHelper.ValidateJwT(token);
dynamic tokenData = (!string.IsNullOrEmpty(decodedToken) ? JObject.Parse(decodedToken) : null);
int requestId = UploadRequestHelper.UpdateRequest(uploadRequestUpdate, (int)tokenData.UserId);
FileUploader.MergeFileAndUpload(uploadRequestUpdate);
response = new Response(Constants.SUCCESS_MSG, Constants.SUCCESS_MSG, requestId);
HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
return new ObjectResult(response);
}
}
}
36 changes: 36 additions & 0 deletions PTransfer/Controllers/RequestPartsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using PTransfer.Core;
using PTransfer.RequestModels;
using PTransfer.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace PTransfer.Controllers {
[ApiController]
[Produces("application/json")]
[Route("/upload-request/parts")]
public class RequestPartsController : ControllerBase {
[HttpPost]
public IActionResult CreateRequestParts([FromBody] UploadRequestPartsCreate uploadRequestPartsCreate) {
Response response;
if (!ModelState.IsValid) {
HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
return BadRequest(ModelState);
}
string token = HttpContext.Request.Headers[Constants.JW_TOKEN_KEY];
if (token == null) {
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
response = new Response(Constants.FORBIDDEN_MSG, Constants.ERROR_MSG, null);
return new ObjectResult(response);
}
dynamic tokenData = JObject.Parse(JwTHelper.ValidateJwT(token));
int partsId = UploadRequestHelper.UploadRequestParts(uploadRequestPartsCreate, (int)tokenData.UserId);
response = new Response(Constants.SUCCESS_MSG, Constants.SUCCESS_MSG, partsId);
return new ObjectResult(response);
}
}
}
2 changes: 1 addition & 1 deletion PTransfer/Controllers/UsersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public IActionResult GetUsers(int id) {
string decodedToken = JwTHelper.ValidateJwT(token);
dynamic tokenData = JObject.Parse(decodedToken);
int userId = tokenData.UserId;
if (string.IsNullOrEmpty(decodedToken)) {
if (string.IsNullOrEmpty(decodedToken) || (id == 0 && userId != id)) {
this.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
response = new Response(Constants.FORBIDDEN_MSG, Constants.ERROR_MSG, null);
return new ObjectResult(response);
Expand Down
81 changes: 81 additions & 0 deletions PTransfer/Core/FileUploader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using MySql.Data.MySqlClient;
using PTransfer.Models;
using PTransfer.Utilities;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace PTransfer.Core {
public class FileUploader {
public static async void MergeFileAndUpload(RequestModels.UploadRequestUpdate uploadRequest) {
UploadRequest request = MergeFile(uploadRequest.RequestId);
if (request != null)
await UploadFile(request);
}
/// <summary>
/// Method to merge the file contents and create the file locally.
/// </summary>
/// <param name="requestId"></param>
/// <returns></returns>
private static UploadRequest MergeFile(int requestId) {
try {
DbHelper dbHelper = new DbHelper();
MySqlConnection connection = dbHelper.GetMySqlConnection();
DataTable dataTable = new DataTable();
using (connection) {
connection.Open();
MySqlCommand command = new MySqlCommand(Constants.SP_GET_UPLOAD_PARTS, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("parRequestId", requestId);
MySqlDataAdapter adapter = new MySqlDataAdapter(command);
adapter.Fill(dataTable);
adapter.Dispose();
command.Dispose();
connection.Close();
}
UploadRequest uploadRequest = new UploadRequest(requestId, dataTable.Rows.Count, null, Convert.ToString(dataTable.Rows[0]["file_hash"]),
Convert.ToString(dataTable.Rows[0]["file_name"]));
uploadRequest.Parts = new List<UploadRequestParts>();
for (int i = 0; i < dataTable.Rows.Count; i++) {
UploadRequestParts part = new UploadRequestParts(Convert.ToInt32(dataTable.Rows[i]["part_number"]),
Convert.ToString(dataTable.Rows[i]["part_value"]));
uploadRequest.Parts.Add(part);
}
string fileContent = uploadRequest.GetRequestParts().Replace("\"","");
File.WriteAllText("Base-Data.txt", fileContent);
uploadRequest.FilePath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar + uploadRequest.FileName;
File.WriteAllBytes(uploadRequest.FilePath, Convert.FromBase64String(fileContent));
if (ValidateHash(uploadRequest.FilePath, uploadRequest.FileHash))
return uploadRequest;
//TODO: Update the error.
return null;
} catch (Exception e) {
Logger.logError(typeof(FileUploader).Name, e.ToString());
return null;
}
}
/// <summary>
/// Method to upload the file to the S3 bucket.
/// </summary>
/// <param name="uploadRequest"></param>
/// <returns></returns>
private static async Task UploadFile(UploadRequest uploadRequest) {
S3Helper s3Helper = new S3Helper(uploadRequest.FileName, uploadRequest.FilePath);
await s3Helper.Upload();
File.Delete(uploadRequest.FilePath);
}
private static bool ValidateHash(string filePath, string originalhash) {
using (var md5 = MD5.Create()) {
using (var stream = File.OpenRead(filePath)) {
return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLowerInvariant().Equals(originalhash);
}
}
}
}
}
98 changes: 98 additions & 0 deletions PTransfer/Core/UploadRequestHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using MySql.Data.MySqlClient;
using PTransfer.RequestModels;
using PTransfer.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace PTransfer.Core {
public class UploadRequestHelper {
/// <summary>
/// Method to create the request.
/// </summary>
/// <param name="uploadRequest"></param>
/// <param name="userId"></param>
/// <returns></returns>
public static int CreateRequest(RequestModels.UploadRequestCreate uploadRequest, int userId) {
try {
DbHelper dbHelper = new DbHelper();
MySqlConnection connection = dbHelper.GetMySqlConnection();
using (connection) {
connection.Open();
MySqlCommand command = new MySqlCommand(Constants.SP_CREATE_OR_UPDATE_UPLOAD_REQUEST, connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.AddWithValue("parRequestId", 0);
command.Parameters.AddWithValue("parParts", uploadRequest.TotalParts);
command.Parameters.AddWithValue("parFileHash", uploadRequest.FileHash);
command.Parameters.AddWithValue("parFileOwner", userId);
command.Parameters.AddWithValue("parFileName", uploadRequest.FileName);
command.Parameters.AddWithValue("parRequestStatus", 0);
int requestId = Convert.ToInt32(command.ExecuteScalar());
command.Dispose();
connection.Close();
return requestId;
}
} catch (Exception e) {
Logger.logError(typeof(UploadRequestHelper).Name, e.ToString());
return -1;
}
}
/// <summary>
/// Method to update the request status.
/// </summary>
/// <param name="uploadRequest"></param>
/// <param name="userId"></param>
/// <returns></returns>
public static int UpdateRequest(RequestModels.UploadRequestUpdate uploadRequest, int userId) {
try {
DbHelper dbHelper = new DbHelper();
MySqlConnection connection = dbHelper.GetMySqlConnection();
using (connection) {
connection.Open();
MySqlCommand command = new MySqlCommand(Constants.SP_CREATE_OR_UPDATE_UPLOAD_REQUEST, connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.AddWithValue("parRequestId", uploadRequest.RequestId);
command.Parameters.AddWithValue("parParts", 0);
command.Parameters.AddWithValue("parFileHash", "");
command.Parameters.AddWithValue("parFileOwner", userId);
command.Parameters.AddWithValue("parFileName", "");
command.Parameters.AddWithValue("parRequestStatus", uploadRequest.RequestStatus);
int requestId = Convert.ToInt32(command.ExecuteScalar());
command.Dispose();
connection.Close();
return requestId;
return requestId;
}
} catch (Exception e) {
Logger.logError(typeof(UploadRequestHelper).Name, e.ToString());
return -1;
}
}
/// <summary>
/// Method to create the request parts.
/// </summary>
/// <param name="requestParts"></param>
/// <param name="userId"></param>
/// <returns></returns>
public static int UploadRequestParts(UploadRequestPartsCreate requestParts, int userId) {
try {
DbHelper dbHelper = new DbHelper();
MySqlConnection connection = dbHelper.GetMySqlConnection();
using (connection) {
connection.Open();
MySqlCommand command = new MySqlCommand(Constants.SP_CREATE_UPLOAD_PARTS, connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.AddWithValue("parRequestId", requestParts.RequestId);
command.Parameters.AddWithValue("parPartValue", requestParts.PartValue);
command.Parameters.AddWithValue("parPartNumber", requestParts.PartNumber);
command.Parameters.AddWithValue("parUserId", userId);
return Convert.ToInt32(command.ExecuteScalar());
}
} catch (Exception e) {
Logger.logError(typeof(UploadRequestHelper).Name, e.ToString());
return -1;
}
}
}
}
40 changes: 40 additions & 0 deletions PTransfer/Models/UploadRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PTransfer.Models {
public class UploadRequest {
public int RequestId { get; set; }
public int TotalParts { get; set; }
public Users FileOwner { get; set; }
[DataType(DataType.Text)]
public string FileHash { get; set; }
[DataType(DataType.Text)]
public string FileName { get; set; }
public string FilePath { get; set; }
public List<UploadRequestParts> Parts { get; set; }

public UploadRequest(int requestId, int totalParts, Users fileOwner, string fileHash, string fileName) {
RequestId = requestId;
TotalParts = totalParts;
FileOwner = fileOwner;
FileHash = fileHash;
FileName = fileName;
}
/// <summary>
/// Method to get the Concatenated Parts in Order.
/// </summary>
/// <returns>All the parts merged as a string</returns>
public string GetRequestParts() {
this.Parts = this.Parts.OrderBy(o => o.PartNumber).ToList();
StringBuilder stringBuilder = new StringBuilder();
for(int i = 0; i < this.Parts.Count; i++) {
stringBuilder.Append(this.Parts[i].PartValue);
}
return stringBuilder.ToString();
}
}
}
16 changes: 16 additions & 0 deletions PTransfer/Models/UploadRequestParts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace PTransfer.Models {
public class UploadRequestParts {
public int PartNumber { get; set; }
public string PartValue { get; set; }

public UploadRequestParts( int partNumber, string partValue) {
PartNumber = partNumber;
PartValue = partValue;
}
}
}
2 changes: 2 additions & 0 deletions PTransfer/PTransfer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.Core" Version="3.7.0.15" />
<PackageReference Include="AWSSDK.S3" Version="3.7.0.16" />
<PackageReference Include="dotenv.net" Version="3.0.0" />
<PackageReference Include="jose-jwt" Version="3.1.1" />
<PackageReference Include="Microsoft.AspNetCore.App" />
Expand Down
17 changes: 17 additions & 0 deletions PTransfer/RequestModels/UploadRequestCreate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace PTransfer.RequestModels {
public class UploadRequestCreate {
public int RequestId { get; set; }
[Required]
public int TotalParts { get; set; }
[Required]
public string FileHash { get; set; }
[Required]
public string FileName { get; set; }
}
}
Loading