mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
Added base API service, with Upload POST.
This commit is contained in:
parent
7d2844b4ed
commit
08539288fb
67
Teknik/Areas/API/APIAreaRegistration.cs
Normal file
67
Teknik/Areas/API/APIAreaRegistration.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Teknik.Areas.API
|
||||
{
|
||||
public class APIAreaRegistration : AreaRegistration
|
||||
{
|
||||
public override string AreaName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "API";
|
||||
}
|
||||
}
|
||||
|
||||
public override void RegisterArea(AreaRegistrationContext context)
|
||||
{
|
||||
#region API v1
|
||||
// Base Routing
|
||||
context.MapSubdomainRoute(
|
||||
"API.Index.v1", // Route name
|
||||
"dev",
|
||||
"API/v1", // URL with parameters
|
||||
new { controller = "API", action = "Index_v1" }, // Parameter defaults
|
||||
new[] { typeof(Controllers.APIController).Namespace }
|
||||
);
|
||||
context.MapSubdomainRoute(
|
||||
"API.Index.v1", // Route name
|
||||
"api",
|
||||
"v1", // URL with parameters
|
||||
new { controller = "API", action = "Index_v1" }, // Parameter defaults
|
||||
new[] { typeof(Controllers.APIController).Namespace }
|
||||
);
|
||||
// Uploads
|
||||
context.MapSubdomainRoute(
|
||||
"API.Upload.v1", // Route name
|
||||
"dev",
|
||||
"API/v1/Upload", // URL with parameters
|
||||
new { controller = "API", action = "Upload_v1" }, // Parameter defaults
|
||||
new[] { typeof(Controllers.APIController).Namespace }
|
||||
);
|
||||
context.MapSubdomainRoute(
|
||||
"API.Upload.v1", // Route name
|
||||
"api",
|
||||
"v1/Upload", // URL with parameters
|
||||
new { controller = "API", action = "Upload_v1" }, // Parameter defaults
|
||||
new[] { typeof(Controllers.APIController).Namespace }
|
||||
);
|
||||
#endregion
|
||||
|
||||
// Default Routing
|
||||
context.MapSubdomainRoute(
|
||||
"API.Index", // Route name
|
||||
"dev",
|
||||
"API", // URL with parameters
|
||||
new { controller = "API", action = "Index" }, // Parameter defaults
|
||||
new[] { typeof(Controllers.APIController).Namespace }
|
||||
);
|
||||
context.MapSubdomainRoute(
|
||||
"API.Index", // Route name
|
||||
"api",
|
||||
"", // URL with parameters
|
||||
new { controller = "API", action = "Index" }, // Parameter defaults
|
||||
new[] { typeof(Controllers.APIController).Namespace }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
131
Teknik/Areas/API/Controllers/APIController.cs
Normal file
131
Teknik/Areas/API/Controllers/APIController.cs
Normal file
@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Teknik.Areas.Upload;
|
||||
using Teknik.Controllers;
|
||||
using Teknik.Helpers;
|
||||
using Teknik.Models;
|
||||
|
||||
namespace Teknik.Areas.API.Controllers
|
||||
{
|
||||
public class APIController : DefaultController
|
||||
{
|
||||
private TeknikEntities db = new TeknikEntities();
|
||||
|
||||
[AllowAnonymous]
|
||||
public ActionResult Index()
|
||||
{
|
||||
return Redirect(Url.SubRouteUrl("help", "Help.Topic", new { topic = "API" }));
|
||||
}
|
||||
|
||||
#region API v1 Actions
|
||||
[AllowAnonymous]
|
||||
public ActionResult Index_v1()
|
||||
{
|
||||
return Redirect(Url.SubRouteUrl("help", "Help.Topic", new { topic = "API" }));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public ActionResult Upload_v1(HttpPostedFileWrapper file, string contentType = null, bool encrypt = false, bool saveKey = false, string key = null, int keySize = 0, string iv = null, int blockSize = 0, bool genDeletionKey = false)
|
||||
{
|
||||
if (file != null)
|
||||
{
|
||||
if (file.ContentLength <= Config.UploadConfig.MaxUploadSize)
|
||||
{
|
||||
// convert file to bytes
|
||||
byte[] fileData = null;
|
||||
int contentLength = file.ContentLength;
|
||||
using (var binaryReader = new BinaryReader(file.InputStream))
|
||||
{
|
||||
fileData = binaryReader.ReadBytes(file.ContentLength);
|
||||
}
|
||||
|
||||
// Need to grab the contentType if it's empty
|
||||
if (string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
contentType = (string.IsNullOrEmpty(file.ContentType)) ? "application/octet-stream" : file.ContentType;
|
||||
}
|
||||
|
||||
// Initialize the key size and block size if empty
|
||||
if (keySize <= 0)
|
||||
keySize = Config.UploadConfig.KeySize;
|
||||
if (blockSize <= 0)
|
||||
blockSize = Config.UploadConfig.BlockSize;
|
||||
|
||||
byte[] data = null;
|
||||
// If they want us to encrypt the file first, do that here
|
||||
if (encrypt)
|
||||
{
|
||||
// Generate key and iv if empty
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
key = Utility.RandomString(keySize);
|
||||
}
|
||||
if (string.IsNullOrEmpty(iv))
|
||||
{
|
||||
iv = Utility.RandomString(blockSize);
|
||||
}
|
||||
|
||||
data = AES.Encrypt(fileData, key, iv);
|
||||
if (data == null || data.Length <= 0)
|
||||
{
|
||||
return Json(new { error = "Unable to encrypt file" });
|
||||
}
|
||||
}
|
||||
|
||||
// Save the file data
|
||||
Upload.Models.Upload upload = Uploader.SaveFile((encrypt) ? data : fileData, contentType, contentLength, iv, key, keySize, blockSize);
|
||||
|
||||
if (upload != null)
|
||||
{
|
||||
// Save the key to the DB if they wanted it to be
|
||||
if (saveKey)
|
||||
{
|
||||
upload.Key = key;
|
||||
db.Entry(upload).State = EntityState.Modified;
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
// Generate delete key if asked to
|
||||
if (genDeletionKey)
|
||||
{
|
||||
string delKey = Utility.RandomString(Config.UploadConfig.DeleteKeyLength);
|
||||
upload.DeleteKey = delKey;
|
||||
db.Entry(upload).State = EntityState.Modified;
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
// Pull all the information together
|
||||
var returnData = new
|
||||
{
|
||||
name = upload.Url,
|
||||
url = Url.SubRouteUrl("upload", "Upload.Download", new { file = upload.Url }),
|
||||
contentType = contentType,
|
||||
contentLength = contentLength,
|
||||
key = key,
|
||||
keySize = keySize,
|
||||
iv = iv,
|
||||
blockSize = blockSize,
|
||||
deletionKey = upload.DeleteKey
|
||||
|
||||
};
|
||||
return Json(new { result = new { name = upload.Url, url = Url.SubRouteUrl("upload", "Upload.Download", new { file = upload.Url }) } }, "text/plain");
|
||||
}
|
||||
return Json(new { error = "Unable to save file" });
|
||||
}
|
||||
else
|
||||
{
|
||||
return Json(new { error = "File Too Large" });
|
||||
}
|
||||
}
|
||||
|
||||
return Json(new { error = "Invalid Upload Request" });
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
36
Teknik/Areas/API/Views/web.config
Normal file
36
Teknik/Areas/API/Views/web.config
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="System.Web.Optimization" />
|
||||
<add namespace="Teknik" />
|
||||
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler"/>
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
@ -34,7 +34,14 @@ namespace Teknik.Areas.Upload.Controllers
|
||||
{
|
||||
if (data.ContentLength <= Config.UploadConfig.MaxUploadSize)
|
||||
{
|
||||
Models.Upload upload = Uploader.SaveFile(data, fileType, iv, null, keySize, blockSize);
|
||||
// convert file to bytes
|
||||
byte[] fileData = null;
|
||||
int contentLength = data.ContentLength;
|
||||
using (var binaryReader = new BinaryReader(data.InputStream))
|
||||
{
|
||||
fileData = binaryReader.ReadBytes(data.ContentLength);
|
||||
}
|
||||
Models.Upload upload = Uploader.SaveFile(fileData, fileType, contentLength, iv, null, keySize, blockSize);
|
||||
if (upload != null)
|
||||
{
|
||||
return Json(new { result = new { name = upload.Url, url = Url.SubRouteUrl("upload", "Upload.Download", new { file = upload.Url }) } }, "text/plain");
|
||||
|
@ -10,22 +10,22 @@ namespace Teknik.Areas.Upload
|
||||
{
|
||||
public static class Uploader
|
||||
{
|
||||
public static Models.Upload SaveFile(HttpPostedFileWrapper file, string contentType)
|
||||
public static Models.Upload SaveFile(byte[] file, string contentType, int contentLength)
|
||||
{
|
||||
return SaveFile(file, contentType, null, null, 256, 128);
|
||||
return SaveFile(file, contentType, contentLength, null, null, 256, 128);
|
||||
}
|
||||
|
||||
public static Models.Upload SaveFile(HttpPostedFileWrapper file, string contentType, string iv)
|
||||
public static Models.Upload SaveFile(byte[] file, string contentType, int contentLength, string iv)
|
||||
{
|
||||
return SaveFile(file, contentType, iv, null, 256, 128);
|
||||
return SaveFile(file, contentType, contentLength, iv, null, 256, 128);
|
||||
}
|
||||
|
||||
public static Models.Upload SaveFile(HttpPostedFileWrapper file, string contentType, string iv, string key)
|
||||
public static Models.Upload SaveFile(byte[] file, string contentType, int contentLength, string iv, string key)
|
||||
{
|
||||
return SaveFile(file, contentType, iv, key, 256, 128);
|
||||
return SaveFile(file, contentType, contentLength, iv, key, 256, 128);
|
||||
}
|
||||
|
||||
public static Models.Upload SaveFile(HttpPostedFileWrapper file, string contentType, string iv, string key, int keySize, int blockSize)
|
||||
public static Models.Upload SaveFile(byte[] file, string contentType, int contentLength, string iv, string key, int keySize, int blockSize)
|
||||
{
|
||||
Config config = Config.Load();
|
||||
TeknikEntities db = new TeknikEntities();
|
||||
@ -39,7 +39,7 @@ namespace Teknik.Areas.Upload
|
||||
string fileName = Utility.GenerateUniqueFileName(config.UploadConfig.UploadDirectory, config.UploadConfig.FileExtension, 10);
|
||||
|
||||
// once we have the filename, lets save the file
|
||||
file.SaveAs(fileName);
|
||||
File.WriteAllBytes(fileName, file);
|
||||
|
||||
// Generate a unique url
|
||||
string extension = (config.UploadConfig.IncludeExtension) ? Utility.GetDefaultExtension(contentType) : string.Empty;
|
||||
@ -55,7 +55,7 @@ namespace Teknik.Areas.Upload
|
||||
upload.Url = url;
|
||||
upload.FileName = fileName;
|
||||
upload.ContentType = (!string.IsNullOrEmpty(contentType)) ? contentType : "application/octet-stream";
|
||||
upload.ContentLength = file.ContentLength;
|
||||
upload.ContentLength = contentLength;
|
||||
upload.Key = key;
|
||||
upload.IV = iv;
|
||||
upload.KeySize = keySize;
|
||||
|
@ -36,17 +36,7 @@ namespace Teknik.Helpers
|
||||
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
|
||||
return Decrypt(data, keyBytes, ivBytes);
|
||||
}
|
||||
public static byte[] Decrypt(byte[] data, string key, string iv, int keySize, int blockSize)
|
||||
{
|
||||
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
|
||||
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
|
||||
return Decrypt(data, keyBytes, ivBytes, keySize, blockSize);
|
||||
}
|
||||
public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
|
||||
{
|
||||
return Decrypt(data, key, iv, 256, 128);
|
||||
}
|
||||
public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv, int keySize, int blockSize)
|
||||
{
|
||||
IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");
|
||||
|
||||
@ -61,17 +51,7 @@ namespace Teknik.Helpers
|
||||
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
|
||||
return Encrypt(data, keyBytes, ivBytes);
|
||||
}
|
||||
public static byte[] Encrypt(byte[] data, string key, string iv, int keySize, int blockSize)
|
||||
{
|
||||
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
|
||||
byte[] ivBytes = Encoding.UTF8.GetBytes(iv);
|
||||
return Encrypt(data, keyBytes, ivBytes, keySize, blockSize);
|
||||
}
|
||||
public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
|
||||
{
|
||||
return Encrypt(data, key, iv, 256, 128);
|
||||
}
|
||||
public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv, int keySize, int blockSize)
|
||||
{
|
||||
IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");
|
||||
|
||||
|
@ -147,6 +147,8 @@
|
||||
<Compile Include="Areas\About\AboutAreaRegistration.cs" />
|
||||
<Compile Include="Areas\About\Controllers\AboutController.cs" />
|
||||
<Compile Include="Areas\About\ViewModels\AboutViewModel.cs" />
|
||||
<Compile Include="Areas\API\APIAreaRegistration.cs" />
|
||||
<Compile Include="Areas\API\Controllers\APIController.cs" />
|
||||
<Compile Include="Areas\Blog\BlogAreaRegistration.cs" />
|
||||
<Compile Include="Areas\Blog\Models\Comment.cs" />
|
||||
<Compile Include="Areas\Blog\ViewModels\BlogViewModel.cs" />
|
||||
@ -307,6 +309,7 @@
|
||||
<Content Include="Areas\Help\Views\Help\Mumble.cshtml" />
|
||||
<Content Include="Areas\Help\Views\Help\Blog.cshtml" />
|
||||
<Content Include="Areas\Help\Views\Help\Upload.cshtml" />
|
||||
<Content Include="Areas\API\Views\web.config" />
|
||||
<None Include="Properties\PublishProfiles\Teknik Dev.pubxml" />
|
||||
<None Include="Scripts\jquery-2.1.4.intellisense.js" />
|
||||
<Content Include="Scripts\bootbox\bootbox.min.js" />
|
||||
@ -364,6 +367,9 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Areas\About\Models\" />
|
||||
<Folder Include="Areas\About\Views\Shared\" />
|
||||
<Folder Include="Areas\API\Models\" />
|
||||
<Folder Include="Areas\API\Views\API\" />
|
||||
<Folder Include="Areas\API\Views\Shared\" />
|
||||
<Folder Include="Areas\Blog\Views\Shared\" />
|
||||
<Folder Include="Areas\Contact\Views\Shared\" />
|
||||
<Folder Include="Areas\Dev\Models\" />
|
||||
|
Loading…
Reference in New Issue
Block a user