Browse Source

Modified API routing and organization.

Modified org of API help.
tags/2.0.3
Teknikode 4 years ago
parent
commit
c00acbc54a

+ 12
- 12
Teknik/Areas/API/APIAreaRegistration.cs View File

@@ -17,33 +17,33 @@ namespace Teknik.Areas.API
#region API v1
// Base Routing
context.MapSubdomainRoute(
"API.Index.v1", // Route name
"APIv1.Index", // Route name
"dev",
"API/v1", // URL with parameters
new { controller = "API", action = "Index_v1" }, // Parameter defaults
new[] { typeof(Controllers.APIController).Namespace }
new { controller = "API", action = "Index" }, // Parameter defaults
new[] { typeof(Controllers.APIv1Controller).Namespace }
);
context.MapSubdomainRoute(
"API.Index.v1", // Route name
"APIv1.Index", // Route name
"api",
"v1", // URL with parameters
new { controller = "API", action = "Index_v1" }, // Parameter defaults
new[] { typeof(Controllers.APIController).Namespace }
new { controller = "API", action = "Index" }, // Parameter defaults
new[] { typeof(Controllers.APIv1Controller).Namespace }
);
// Uploads
context.MapSubdomainRoute(
"API.Upload.v1", // Route name
"APIv1.Upload", // Route name
"dev",
"API/v1/Upload", // URL with parameters
new { controller = "API", action = "Upload_v1" }, // Parameter defaults
new[] { typeof(Controllers.APIController).Namespace }
new { controller = "API", action = "Upload" }, // Parameter defaults
new[] { typeof(Controllers.APIv1Controller).Namespace }
);
context.MapSubdomainRoute(
"API.Upload.v1", // Route name
"APIv1.Upload", // Route name
"api",
"v1/Upload", // URL with parameters
new { controller = "API", action = "Upload_v1" }, // Parameter defaults
new[] { typeof(Controllers.APIController).Namespace }
new { controller = "API", action = "Upload" }, // Parameter defaults
new[] { typeof(Controllers.APIv1Controller).Namespace }
);
#endregion


+ 1
- 107
Teknik/Areas/API/Controllers/APIController.cs View File

@@ -19,113 +19,7 @@ namespace Teknik.Areas.API.Controllers
[AllowAnonymous]
public ActionResult Index()
{
return Redirect(Url.SubRouteUrl("help", "Help.Topic", new { topic = "API" }));
return Redirect(Url.SubRouteUrl("help", "Help.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
}
}

+ 123
- 0
Teknik/Areas/API/Controllers/APIv1Controller.cs View File

@@ -0,0 +1,123 @@
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 APIv1Controller : DefaultController
{
private TeknikEntities db = new TeknikEntities();

[AllowAnonymous]
public ActionResult Index()
{
return Redirect(Url.SubRouteUrl("help", "Help.Topic", new { topic = "API" }));
}

[HttpPost]
[AllowAnonymous]
public ActionResult Upload(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
{
url = Url.SubRouteUrl("upload", "Upload.Download", new { file = upload.Url }),
fileName = upload.Url,
contentType = contentType,
contentLength = contentLength,
key = key,
keySize = keySize,
iv = iv,
blockSize = blockSize,
deletionKey = upload.DeleteKey

};
return Json(new { result = returnData });
}
return Json(new { error = "Unable to save file" });
}
else
{
return Json(new { error = "File Too Large" });
}
}

return Json(new { error = "Invalid Upload Request" });
}
}
}

+ 3
- 3
Teknik/Areas/About/Views/About/Index.cshtml View File

@@ -17,14 +17,14 @@
<div class="col-sm-4 col-sm-offset-2 text-center">
<h4><a href="@Url.SubRouteUrl("paste", "Paste.Index")">Fast and Secure Pastebin</a></h4>
<h4><a href="@Url.SubRouteUrl("upload", "Upload.Index")">Encrypted File Uploads</a></h4>
<h4><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Mail" })">Free Email Address</a></h4>
<h4><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "API" })">Easy to Use API</a></h4>
<h4><a href="@Url.SubRouteUrl("help", "Help.Mail")">Free Email Address</a></h4>
<h4><a href="@Url.SubRouteUrl("help", "Help.API")">Easy to Use API</a></h4>
<h4><a href="@Url.SubRouteUrl("git", "Git.Index")">Personal Git Repositories</a></h4>
</div>
<div class="col-sm-4 text-center">
<h4><a href="@Url.SubRouteUrl("blog", "Blog.Blog")">Personal Blog</a></h4>
<h4><a href="@Url.SubRouteUrl("podcast", "Podcast.Index")">Entertaining Podcasts</a></h4>
<h4><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Mumble" })">Mumble Server</a></h4>
<h4><a href="@Url.SubRouteUrl("help", "Help.Mumble")">Mumble Server</a></h4>
<h4><a href="@Url.SubRouteUrl("transparency", "Transparency.Index")">Full Transparency</a></h4>
<h4><a href="@Url.SubRouteUrl("git", "Git.Index", new { username = "Teknikode", repository = "Teknik" })">Completely Open Source</a></h4>
</div>

+ 55
- 31
Teknik/Areas/Help/Controllers/HelpController.cs View File

@@ -20,44 +20,68 @@ namespace Teknik.Areas.Help.Controllers
}

[AllowAnonymous]
public ActionResult Topic(string topic)
public ActionResult API(string version, string service)
{
ViewBag.Title = topic + " Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();

string view = string.Empty;
switch(topic.ToLower())
if (string.IsNullOrEmpty(version) && string.IsNullOrEmpty(service))
{
case "api":
view = "~/Areas/Help/Views/Help/API.cshtml";
break;
case "blog":
view = "~/Areas/Help/Views/Help/Blog.cshtml";
break;
case "git":
view = "~/Areas/Help/Views/Help/Git.cshtml";
break;
case "irc":
view = "~/Areas/Help/Views/Help/IRC.cshtml";
break;
case "mail":
view = "~/Areas/Help/Views/Help/Mail.cshtml";
break;
case "mumble":
view = "~/Areas/Help/Views/Help/Mumble.cshtml";
break;
case "upload":
view = "~/Areas/Help/Views/Help/Upload.cshtml";
break;
default:
break;
ViewBag.Title = "API Help - " + Config.Title;
return View("~/Areas/Help/Views/Help/API/API.cshtml", model);
}

if (!string.IsNullOrEmpty(view))
else if(!string.IsNullOrEmpty(version) && !string.IsNullOrEmpty(service))
{
return View(view, model);
ViewBag.Title = service + " API " + version + " Help - " + Config.Title;
return View("~/Areas/Help/Views/Help/API/" + version + "/" + service + ".cshtml", model);
}
return RedirectToRoute("*.Error.Http404");
}

[AllowAnonymous]
public ActionResult Blog()
{
ViewBag.Title = "Blogging Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();
return View("~/Areas/Help/Views/Help/Blog.cshtml", model);
}

[AllowAnonymous]
public ActionResult Git()
{
ViewBag.Title = "Git Service Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();
return View("~/Areas/Help/Views/Help/Git.cshtml", model);
}

[AllowAnonymous]
public ActionResult IRC()
{
ViewBag.Title = "IRC Server Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();
return View("~/Areas/Help/Views/Help/IRC.cshtml", model);
}

[AllowAnonymous]
public ActionResult Mail()
{
ViewBag.Title = "Mail Server Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();
return View("~/Areas/Help/Views/Help/Mail.cshtml", model);
}

[AllowAnonymous]
public ActionResult Mumble()
{
ViewBag.Title = "Mumble Server Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();
return View("~/Areas/Help/Views/Help/Mumble.cshtml", model);
}

[AllowAnonymous]
public ActionResult Upload()
{
ViewBag.Title = "Upload Service Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();
return View("~/Areas/Help/Views/Help/Upload.cshtml", model);
}
}
}

+ 90
- 6
Teknik/Areas/Help/HelpAreaRegistration.cs View File

@@ -23,10 +23,52 @@ namespace Teknik.Areas.Help
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Topic", // Route name
"Help.API", // Route name
"dev",
"Help/{topic}", // URL with parameters
new { controller = "Help", action = "Topic" }, // Parameter defaults
"Help/API/{version}/{service}", // URL with parameters
new { controller = "Help", action = "API", version = UrlParameter.Optional, service = UrlParameter.Optional }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Blog", // Route name
"dev",
"Help/Blog", // URL with parameters
new { controller = "Help", action = "Blog" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Git", // Route name
"dev",
"Help/Git", // URL with parameters
new { controller = "Help", action = "Git" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.IRC", // Route name
"dev",
"Help/IRC", // URL with parameters
new { controller = "Help", action = "IRC" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Mail", // Route name
"dev",
"Help/Mail", // URL with parameters
new { controller = "Help", action = "Mail" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Mumble", // Route name
"dev",
"Help/Mumble", // URL with parameters
new { controller = "Help", action = "Mumble" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Upload", // Route name
"dev",
"Help/Upload", // URL with parameters
new { controller = "Help", action = "Upload" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
@@ -37,10 +79,52 @@ namespace Teknik.Areas.Help
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Topic", // Route name
"Help.API", // Route name
"help",
"API/{version}/{service}", // URL with parameters
new { controller = "Help", action = "API", version = UrlParameter.Optional, service = UrlParameter.Optional }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Blog", // Route name
"help",
"Blog", // URL with parameters
new { controller = "Help", action = "Blog" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Git", // Route name
"help",
"Git", // URL with parameters
new { controller = "Help", action = "Git" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.IRC", // Route name
"help",
"IRC", // URL with parameters
new { controller = "Help", action = "IRC" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Mail", // Route name
"help",
"Mail", // URL with parameters
new { controller = "Help", action = "Mail" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Mumble", // Route name
"help",
"Mumble", // URL with parameters
new { controller = "Help", action = "Mumble" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Upload", // Route name
"help",
"{topic}", // URL with parameters
new { controller = "Help", action = "Topic" }, // Parameter defaults
"Upload", // URL with parameters
new { controller = "Help", action = "Upload" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);


+ 38
- 0
Teknik/Areas/Help/Views/Help/API/API.cshtml View File

@@ -0,0 +1,38 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel

@Styles.Render("~/Content/help");

<div class="container">
<div class="row api">
<div class="col-sm-4">
<h3><b>API Versions</b></h3>
<h4>Version 1</h4>
<p>
<ul class="list-unstyled">
<li><a href="@Url.SubRouteUrl("help", "Help.API", new { version = "v1", service = "Upload" })">Upload Service</a></li>
</ul>
</p>
</div>
<div class="col-sm-8">
<h2><b>Teknik API</b></h2>
<hr>
<p>
The Teknik API is free for everyone to use, and is defined on a per service basis.
<br />
<br />
The general API calls can be summarized as follows: <code>@Url.SubRouteUrl("api", "Api.Index")/v@(Model.Config.ApiConfig.Version)/<b>Service</b>/<b>Action</b></code>
</p>
<h3>Responses</h3>
<p>
All responses are returned as json. The returned json can contain any of the following sections.
<br />
<br />
<strong>Results</strong>
<pre><code>{"result":{"&lt;resultData&gt;":"&lt;value&gt;"}}</code></pre>
<strong>Errors</strong>
<pre><code>{"error":{"message":"&lt;errorMessage&gt;"}}</code></pre>
</p>
<hr />
</div>
</div>
</div>

Teknik/Areas/Help/Views/Help/Api.cshtml → Teknik/Areas/Help/Views/Help/API/v1/Upload.cshtml View File

@@ -4,31 +4,12 @@

<div class="container">
<div class="row api">
<h2><b>Teknik API</b></h2>
<hr>
<h3>Overview</h3>
<p>
The Teknik API is free for everyone to use, and is defined on a per service basis.
<br />
<br />
The general API calls can be summarized as follows: <code>@Url.SubRouteUrl("api", "Api.Index", new { service = "<b>Service</b>", action = "<b>Action</b>", version = Model.Config.ApiConfig.Version })</code>
</p>
<h4>Responses</h4>
<p>
All responses are returned as json. The returned json can contain any of the following sections.
<br />
<br />
<strong>Results</strong>
<pre><code>{"results":{"&lt;resultType&gt;":{"&lt;resultData&gt;":"&lt;value&gt;"}}}</code></pre>
<strong>Errors</strong>
<pre><code>{"error":{"code":&lt;value&gt;, "message":"&lt;errorMessage&gt;"}}</code></pre>
</p>
<h3><b>Upload</b></h3>
<h2><b>Upload Service</b></h2>
<hr>
<p>This is a description of the API commands available for the Upload service.</p>
<h4>Upload a File</h4>
<pre><code>POST @Url.SubRouteUrl("api", "Api.Index", new { service = "Upload", action = "Post", version = Model.Config.ApiConfig.Version })</code></pre>
<h5>Parameters</h5>
<h3>Upload a File</h3>
<pre><code>POST @Url.SubRouteUrl("api", "Api.Index", new { service = "Upload", action = "Post", version = "v1" })</code></pre>
<h4>Parameters</h4>
<table>
<thead>
<tr>
@@ -56,7 +37,7 @@
</tr>
<tr>
<td>
<code>encrypt</code>
<code>contentType</code>
</td>
<td>
<code>string</code>
@@ -65,7 +46,35 @@
<var>no</var>
</td>
<td>
If you want the file to be encrypted server side. This will regenerate the key and/or iv if none are passed in. Choose <code>yes</code> or <code>no</code>
The content-type of the file you are uploading. Only required if the file being uploaded is already encrypted.
</td>
</tr>
<tr>
<td>
<code>encrypt</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<var>false</var>
</td>
<td>
If you want the file to be encrypted server side. This will regenerate the key and/or iv if none are passed in.
</td>
</tr>
<tr>
<td>
<code>saveKey</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<var>false</var>
</td>
<td>
Saves the passed in or generated key to the server. This will make it so that on download, the file will decrypt server side.
</td>
</tr>
<tr>
@@ -82,6 +91,20 @@
If you want the file to be decrypted server side, include the key.
</td>
</tr>
<tr>
<td>
<code>keySize</code>
</td>
<td>
<code>int</code>
</td>
<td>
<var>@Model.Config.UploadConfig.KeySize</var>
</td>
<td>
The size of the key provided in bytes. Only needed if encrypting and no key is provided.
</td>
</tr>
<tr>
<td>
<code>iv</code>
@@ -96,24 +119,38 @@
If the file has been encrypted and you want it decrypted (Both Server and Client Side), include the iv.
</td>
</tr>
<tr>
<td>
<code>blockSize</code>
</td>
<td>
<code>int</code>
</td>
<td>
<var>@Model.Config.UploadConfig.BlockSize</var>
</td>
<td>
The size of the iv provided in bytes. Only needed if encrypting and no iv is provided.
</td>
</tr>
<tr>
<td>
<code>getDeletionKey</code>
</td>
<td>
<code>string</code>
<code>bool</code>
</td>
<td>
<var>no</var>
<var>false</var>
</td>
<td>
Whether you would like to create a deletion link. Choose <code>yes</code> or <code>no</code>
Generates a deletion key.
</td>
</tr>
</tbody>
</table>
<h5>Response</h5>
<pre><code>{"results":{"file":{"name":"<var>fileName</var>", "url":"<var>url</var>", "type":"<var>file_type</var>", "size":<var>size</var>, "key":<var>key</var>, "iv":<var>iv</var>, "deletionKey":<var>deletionKey</var>}}}</code></pre>
<h4>Response</h4>
<pre><code>{"result":{"url":"<var>url</var>", "fileName":"<var>fileName</var>", "contentType":"<var>contentType</var>", "contentLength":<var>contentLength</var>, "key":<var>key</var>, "keySize":<var>keySize</var>, "iv":<var>iv</var>, "blockSize":<var>blockSize</var>, "deletionKey":<var>deletionKey</var>}}</code></pre>
<table>
<thead>
<tr>
@@ -125,29 +162,29 @@
<tbody>
<tr>
<td>
<code>name</code>
<code>url</code>
</td>
<td>
<code>string</code>
</td>
<td>
The filename of the uploaded file.
The direct url to the uploaded file. The key is apended to the url as an anchor tag.
</td>
</tr>
<tr>
<td>
<code>url</code>
<code>fileName</code>
</td>
<td>
<code>string</code>
</td>
<td>
The direct url to the uploaded file. The key is apended to the url as an anchor tag.
The filename of the uploaded file.
</td>
</tr>
<tr>
<td>
<code>type</code>
<code>contentType</code>
</td>
<td>
<code>string</code>
@@ -158,7 +195,7 @@
</tr>
<tr>
<td>
<code>size</code>
<code>contentLength</code>
</td>
<td>
<code>integer</code>
@@ -175,9 +212,21 @@
<code>string</code>
</td>
<td>
<strong>Optional</strong>
The key that was used to encrypt the file.
</td>
</tr>
<tr>
<td>
<code>keySize</code>
</td>
<td>
<code>int</code>
</td>
<td>
The size of the key used in bytes.
</td>
</tr>
<tr>
<td>
<code>iv</code>
@@ -186,9 +235,21 @@
<code>string</code>
</td>
<td>
<strong>Optional</strong>
The iv that was used to encrypt the file.
</td>
</tr>
<tr>
<td>
<code>blockSize</code>
</td>
<td>
<code>int</code>
</td>
<td>
The size of the iv used in bytes.
</td>
</tr>
<tr>
<td>
<code>deletionKey</code>
@@ -198,14 +259,17 @@
</td>
<td>
<strong>Optional</strong>
The deletion key for file. Use it as follows: <code>@Url.SubRouteUrl("u", "Upload.Upload", new { file = "<var>file.jpg</var>", key = "<var>deletionKey</var>" })</code>
The deletion key for file. Use it as follows: <code>@Url.SubRouteUrl("u", "Upload.Delete", new { file = "file.jpg", key = "deletionKey" })</code>
</td>
</tr>
</tbody>
</table>
<h5>Example</h5>
<pre><code>$ curl -F "getDeletionKey=yes" -F "encrypt=yes" -F "file=@("@")image.png" @Url.SubRouteUrl("api", "Api.Index", new { service = "Upload", version = Model.Config.ApiConfig.Version })</code></pre>
<h4>Example</h4>
<pre><code>$ curl -F "getDeletionKey=true" -F "encrypt=yes" -F "file=@("@")image.png" @Url.SubRouteUrl("api", "APIv1.Upload")</code></pre>
<p>
This will upload the file <var>image.png</var>, encrypt it, and then generate a deletion key.
</p>
<br />
<br />
</div>
</div>
</div>

+ 7
- 7
Teknik/Areas/Help/Views/Help/Index.cshtml View File

@@ -15,19 +15,19 @@
<hr>
<h3 class="text-center">Help Topics</h3>
<dl class="dl-horizontal">
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "API" })">API</a></dt>
<dt><a href="@Url.SubRouteUrl("help", "Help.API")">API</a></dt>
<dd>Open API available to interact with the difference services.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Blog" })">Blogging</a></dt>
<dt><a href="@Url.SubRouteUrl("help", "Help.Blog")">Blogging</a></dt>
<dd>Blogging platform available to the users and visible to the public.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Git" })">Git Repositories</a></dt>
<dt><a href="@Url.SubRouteUrl("help", "Help.Git")">Git Repositories</a></dt>
<dd>Unlimited public and private git repositories.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "IRC" })">IRC Network</a></dt>
<dt><a href="@Url.SubRouteUrl("help", "Help.IRC")">IRC Network</a></dt>
<dd>IRC network that uses the Teknik userbase for nickname authentication.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Mail" })">Mail Server</a></dt>
<dt><a href="@Url.SubRouteUrl("help", "Help.Mail")">Mail Server</a></dt>
<dd>Mail service with IMAP and POP3 support with <b>1 GB</b> storage.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Mumble" })">Mumble Chat Server</a></dt>
<dt><a href="@Url.SubRouteUrl("help", "Help.Mumble")">Mumble Chat Server</a></dt>
<dd>The public Mumble server and configuration settings needed.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Upload" })">Uploads</a></dt>
<dt><a href="@Url.SubRouteUrl("help", "Help.Upload")">Uploads</a></dt>
<dd>How the Upload service works and special considerations.</dd>
</dl>
</div>

+ 3
- 3
Teknik/Areas/Home/Views/Home/Index.cshtml View File

@@ -54,7 +54,7 @@
</div>
</div>
</a>
<a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Mumble"})">
<a href="@Url.SubRouteUrl("help", "Help.Mumble")">
<div class="col-md-3 text-center">
<div class="thumbnail">
<br />
@@ -74,7 +74,7 @@
</div>
<br/>
<div class="row">
<a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Mail"})">
<a href="@Url.SubRouteUrl("help", "Help.Mail")">
<div class="col-md-3 text-center">
<div class="thumbnail">
<br/>
@@ -107,7 +107,7 @@
</div>
</div>
</a>
<a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "IRC"})">
<a href="@Url.SubRouteUrl("help", "Help.IRC")">
<div class="col-md-3 text-center">
<div class="thumbnail">
<br/>

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

@@ -64,7 +64,7 @@ namespace Teknik.Areas.Upload.Controllers
if (upload != null)
{
// We don't have the key, so we need to decrypt it client side
if (string.IsNullOrEmpty(upload.Key))
if (string.IsNullOrEmpty(upload.Key) && !string.IsNullOrEmpty(upload.IV))
{
DownloadViewModel model = new DownloadViewModel();
model.FileName = file;
@@ -81,7 +81,7 @@ namespace Teknik.Areas.Upload.Controllers
// Read in the file
byte[] encData = System.IO.File.ReadAllBytes(upload.FileName);
// Decrypt the data
byte[] data = AES.Decrypt(encData, upload.Key, upload.IV, upload.KeySize, upload.BlockSize);
byte[] data = AES.Decrypt(encData, upload.Key, upload.IV);

// Create File
var cd = new System.Net.Mime.ContentDisposition

+ 50
- 38
Teknik/Areas/Upload/Scripts/Download.js View File

@@ -12,50 +12,62 @@ function downloadFile() {

xhr.onload = function (e) {
if (this.status == 200) {
var worker = new Worker(encScriptSrc);

worker.addEventListener('message', function (e) {
switch (e.data.cmd) {
case 'progress':
var percentComplete = Math.round(e.data.processed * 100 / e.data.total);
$("#progress").children('.progress-bar').css('width', (percentComplete / 2) + 50 + '%');
$("#progress").children('.progress-bar').html(percentComplete + '% Decrypted');
break;
case 'finish':
$('#progress').children('.progress-bar').css('width', '100%');
$('#progress').children('.progress-bar').html('Complete');
if (fileType == null || fileType == '')
{
fileType = "application/octet-stream";
}
var blob = new Blob([e.data.buffer], { type: fileType });
saveAs(blob, fileName);
if (iv != '' && key != '') {
var worker = new Worker(encScriptSrc);

// DO SOMETHING
break;
worker.addEventListener('message', function (e) {
switch (e.data.cmd) {
case 'progress':
var percentComplete = Math.round(e.data.processed * 100 / e.data.total);
$("#progress").children('.progress-bar').css('width', (percentComplete / 2) + 50 + '%');
$("#progress").children('.progress-bar').html(percentComplete + '% Decrypted');
break;
case 'finish':
$('#progress').children('.progress-bar').css('width', '100%');
$('#progress').children('.progress-bar').html('Complete');
if (fileType == null || fileType == '') {
fileType = "application/octet-stream";
}
var blob = new Blob([e.data.buffer], { type: fileType });

// prompt save-as
saveAs(blob, fileName);
break;
}
});

worker.onerror = function (err) {
// An error occured
$("#progress").children('.progress-bar').css('width', '100%');
$("#progress").children('.progress-bar').removeClass('progress-bar-success');
$("#progress").children('.progress-bar').addClass('progress-bar-danger');
$("#progress").children('.progress-bar').html('Error Occured');
}
});

worker.onerror = function (err) {
// An error occured
$("#progress").children('.progress-bar').css('width', '100%');
$("#progress").children('.progress-bar').removeClass('progress-bar-success');
$("#progress").children('.progress-bar').addClass('progress-bar-danger');
$("#progress").children('.progress-bar').html('Error Occured');
// Execute worker with data
var objData =
{
cmd: 'decrypt',
script: aesScriptSrc,
key: key,
iv: iv,
chunkSize: chunkSize,
file: this.response
};
worker.postMessage(objData, [objData.file]);
}
else {
$('#progress').children('.progress-bar').css('width', '100%');
$('#progress').children('.progress-bar').html('Complete');
if (fileType == null || fileType == '') {
fileType = "application/octet-stream";
}
var blob = new Blob([e.data.buffer], { type: fileType });

// Execute worker with data
var objData =
{
cmd: 'decrypt',
script: aesScriptSrc,
key: key,
iv: iv,
chunkSize: chunkSize,
file: this.response
};
worker.postMessage(objData, [objData.file]);
// prompt save-as
saveAs(blob, fileName);
}
}
};


+ 4
- 1
Teknik/Teknik.csproj View File

@@ -149,6 +149,7 @@
<Compile Include="Areas\About\ViewModels\AboutViewModel.cs" />
<Compile Include="Areas\API\APIAreaRegistration.cs" />
<Compile Include="Areas\API\Controllers\APIController.cs" />
<Compile Include="Areas\API\Controllers\APIv1Controller.cs" />
<Compile Include="Areas\Blog\BlogAreaRegistration.cs" />
<Compile Include="Areas\Blog\Models\Comment.cs" />
<Compile Include="Areas\Blog\ViewModels\BlogViewModel.cs" />
@@ -302,7 +303,7 @@
<Content Include="Areas\Help\Views\web.config" />
<Content Include="Areas\Help\Views\_ViewStart.cshtml" />
<Content Include="Areas\Help\Views\Help\Index.cshtml" />
<Content Include="Areas\Help\Views\Help\API.cshtml" />
<Content Include="Areas\Help\Views\Help\API\API.cshtml" />
<Content Include="Areas\Help\Views\Help\Git.cshtml" />
<Content Include="Areas\Help\Views\Help\IRC.cshtml" />
<Content Include="Areas\Help\Views\Help\Mail.cshtml" />
@@ -310,6 +311,7 @@
<Content Include="Areas\Help\Views\Help\Blog.cshtml" />
<Content Include="Areas\Help\Views\Help\Upload.cshtml" />
<Content Include="Areas\API\Views\web.config" />
<Content Include="Areas\Help\Views\Help\API\v1\Upload.cshtml" />
<None Include="Properties\PublishProfiles\Teknik Dev.pubxml" />
<None Include="Scripts\jquery-2.1.4.intellisense.js" />
<Content Include="Scripts\bootbox\bootbox.min.js" />
@@ -368,6 +370,7 @@
<Folder Include="Areas\About\Models\" />
<Folder Include="Areas\About\Views\Shared\" />
<Folder Include="Areas\API\Models\" />
<Folder Include="Areas\API\Views\APIv1\" />
<Folder Include="Areas\API\Views\API\" />
<Folder Include="Areas\API\Views\Shared\" />
<Folder Include="Areas\Blog\Views\Shared\" />

Loading…
Cancel
Save