Browse Source

Added base API service, with Upload POST.

tags/2.0.3
Teknikode 4 years ago
parent
commit
08539288fb

+ 67
- 0
Teknik/Areas/API/APIAreaRegistration.cs View 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
- 0
Teknik/Areas/API/Controllers/APIController.cs View 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
- 0
Teknik/Areas/API/Views/web.config View 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>

+ 8
- 1
Teknik/Areas/Upload/Controllers/UploadController.cs View File

@@ -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");

+ 9
- 9
Teknik/Areas/Upload/Uploader.cs View File

@@ -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;

+ 0
- 20
Teknik/Helpers/Crypto.cs View File

@@ -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");


+ 6
- 0
Teknik/Teknik.csproj View File

@@ -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…
Cancel
Save