@@ -32,6 +32,13 @@ namespace Teknik.Areas.API | |||
new { controller = "APIv1", action = "Upload" }, // Parameter defaults | |||
new[] { typeof(Controllers.APIv1Controller).Namespace } | |||
); | |||
context.MapSubdomainRoute( | |||
"API.v1.Paste", // Route name | |||
new List<string>() { "dev", "api" }, | |||
"v1/Paste", // URL with parameters | |||
new { controller = "APIv1", action = "Paste" }, // Parameter defaults | |||
new[] { typeof(Controllers.APIv1Controller).Namespace } | |||
); | |||
#endregion | |||
// Default Routing |
@@ -6,9 +6,11 @@ using System.Linq; | |||
using System.Web; | |||
using System.Web.Mvc; | |||
using Teknik.Areas.Upload; | |||
using Teknik.Areas.Paste; | |||
using Teknik.Controllers; | |||
using Teknik.Helpers; | |||
using Teknik.Models; | |||
using System.Text; | |||
namespace Teknik.Areas.API.Controllers | |||
{ | |||
@@ -118,5 +120,32 @@ namespace Teknik.Areas.API.Controllers | |||
return Json(new { error = new { message = "Exception: " + ex.Message } }); | |||
} | |||
} | |||
[HttpPost] | |||
[AllowAnonymous] | |||
public ActionResult Paste(string content, string title = "", string syntax = "auto", string expireUnit = "never", int expireLength = 1, string password = "", bool hide = false) | |||
{ | |||
try | |||
{ | |||
Paste.Models.Paste paste = PasteHelper.CreatePaste(content, title, syntax, expireUnit, expireLength, password, hide); | |||
db.Pastes.Add(paste); | |||
db.SaveChanges(); | |||
return Json(new { result = new { | |||
id = paste.Url, | |||
url = Url.SubRouteUrl("paste", "Paste.View", new { type = "Full", url = paste.Url, password = password }), | |||
title = paste.Title, | |||
syntax = paste.Syntax, | |||
expiration = paste.ExpireDate, | |||
password = password | |||
} | |||
}); | |||
} | |||
catch (Exception ex) | |||
{ | |||
return Json(new { error = new { message = "Exception: " + ex.Message } }); | |||
} | |||
} | |||
} | |||
} |
@@ -12,6 +12,7 @@ using Teknik.Controllers; | |||
using Teknik.Helpers; | |||
using Teknik.Models; | |||
namespace Teknik.Areas.Paste.Controllers | |||
{ | |||
public class PasteController : DefaultController | |||
@@ -39,7 +40,7 @@ namespace Teknik.Areas.Paste.Controllers | |||
db.SaveChanges(); | |||
// Check Expiration | |||
if (CheckExpiration(paste)) | |||
if (PasteHelper.CheckExpiration(paste)) | |||
{ | |||
db.Pastes.Remove(paste); | |||
db.SaveChanges(); | |||
@@ -108,66 +109,7 @@ namespace Teknik.Areas.Paste.Controllers | |||
{ | |||
try | |||
{ | |||
Models.Paste paste = db.Pastes.Create(); | |||
paste.DatePosted = DateTime.Now; | |||
paste.Url = Utility.RandomString(Config.PasteConfig.UrlLength); | |||
paste.MaxViews = 0; | |||
paste.Views = -1; | |||
// Figure out the expire date (null if 'never' or 'visit') | |||
if (model.ExpireLength.HasValue || model.ExpireUnit == "never") | |||
{ | |||
switch (model.ExpireUnit) | |||
{ | |||
case "never": | |||
break; | |||
case "view": | |||
paste.MaxViews = model.ExpireLength ?? 0; | |||
break; | |||
case "minute": | |||
paste.ExpireDate = paste.DatePosted.AddMinutes(model.ExpireLength ?? 1); | |||
break; | |||
case "hour": | |||
paste.ExpireDate = paste.DatePosted.AddHours(model.ExpireLength ?? 1); | |||
break; | |||
case "day": | |||
paste.ExpireDate = paste.DatePosted.AddDays(model.ExpireLength ?? 1); | |||
break; | |||
case "month": | |||
paste.ExpireDate = paste.DatePosted.AddMonths(model.ExpireLength ?? 1); | |||
break; | |||
case "year": | |||
paste.ExpireDate = paste.DatePosted.AddYears(model.ExpireLength ?? 1); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
// Set the hashed password if one is provided and encrypt stuff | |||
if (!string.IsNullOrEmpty(model.Password)) | |||
{ | |||
string key = Utility.RandomString(Config.PasteConfig.KeySize / 8); | |||
string iv = Utility.RandomString(Config.PasteConfig.BlockSize / 8); | |||
paste.HashedPassword = Helpers.SHA384.Hash(key, model.Password); | |||
// Encrypt Content | |||
byte[] data = Encoding.Unicode.GetBytes(model.Content); | |||
byte[] ivBytes = Encoding.Unicode.GetBytes(iv); | |||
byte[] keyBytes = AES.CreateKey(model.Password, ivBytes, Config.PasteConfig.KeySize); | |||
byte[] encData = AES.Encrypt(data, keyBytes, ivBytes); | |||
model.Content = Encoding.Unicode.GetString(encData); | |||
paste.Key = key; | |||
paste.KeySize = Config.PasteConfig.KeySize; | |||
paste.IV = iv; | |||
paste.BlockSize = Config.PasteConfig.BlockSize; | |||
} | |||
paste.Content = model.Content; | |||
paste.Title = model.Title; | |||
paste.Syntax = model.Syntax; | |||
paste.Hide = model.Hide; | |||
Models.Paste paste = PasteHelper.CreatePaste(model.Content, model.Title, model.Syntax, model.ExpireUnit, model.ExpireLength ?? 1, model.Password, model.Hide); | |||
db.Pastes.Add(paste); | |||
db.SaveChanges(); | |||
@@ -181,15 +123,5 @@ namespace Teknik.Areas.Paste.Controllers | |||
} | |||
return View("~/Areas/Paste/Views/Paste/Index.cshtml", model); | |||
} | |||
private bool CheckExpiration(Models.Paste paste) | |||
{ | |||
if (paste.ExpireDate != null && DateTime.Now >= paste.ExpireDate) | |||
return true; | |||
if (paste.MaxViews > 0 && paste.Views > paste.MaxViews) | |||
return true; | |||
return false; | |||
} | |||
} | |||
} |
@@ -0,0 +1,88 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Web; | |||
using Teknik.Configuration; | |||
using Teknik.Helpers; | |||
using Teknik.Models; | |||
namespace Teknik.Areas.Paste | |||
{ | |||
public static class PasteHelper | |||
{ | |||
public static Models.Paste CreatePaste(string content, string title = "", string syntax = "auto", string expireUnit = "never", int expireLength = 1, string password = "", bool hide = false) | |||
{ | |||
Config config = Config.Load(); | |||
Models.Paste paste = new Models.Paste(); | |||
paste.DatePosted = DateTime.Now; | |||
paste.Url = Utility.RandomString(config.PasteConfig.UrlLength); | |||
paste.MaxViews = 0; | |||
paste.Views = -1; | |||
// Figure out the expire date (null if 'never' or 'visit') | |||
switch (expireUnit.ToLower()) | |||
{ | |||
case "never": | |||
break; | |||
case "view": | |||
paste.MaxViews = expireLength; | |||
break; | |||
case "minute": | |||
paste.ExpireDate = paste.DatePosted.AddMinutes(expireLength); | |||
break; | |||
case "hour": | |||
paste.ExpireDate = paste.DatePosted.AddHours(expireLength); | |||
break; | |||
case "day": | |||
paste.ExpireDate = paste.DatePosted.AddDays(expireLength); | |||
break; | |||
case "month": | |||
paste.ExpireDate = paste.DatePosted.AddMonths(expireLength); | |||
break; | |||
case "year": | |||
paste.ExpireDate = paste.DatePosted.AddYears(expireLength); | |||
break; | |||
default: | |||
break; | |||
} | |||
// Set the hashed password if one is provided and encrypt stuff | |||
if (!string.IsNullOrEmpty(password)) | |||
{ | |||
string key = Utility.RandomString(config.PasteConfig.KeySize / 8); | |||
string iv = Utility.RandomString(config.PasteConfig.BlockSize / 8); | |||
paste.HashedPassword = Helpers.SHA384.Hash(key, password); | |||
// Encrypt Content | |||
byte[] data = Encoding.Unicode.GetBytes(content); | |||
byte[] ivBytes = Encoding.Unicode.GetBytes(iv); | |||
byte[] keyBytes = AES.CreateKey(password, ivBytes, config.PasteConfig.KeySize); | |||
byte[] encData = AES.Encrypt(data, keyBytes, ivBytes); | |||
content = Encoding.Unicode.GetString(encData); | |||
paste.Key = key; | |||
paste.KeySize = config.PasteConfig.KeySize; | |||
paste.IV = iv; | |||
paste.BlockSize = config.PasteConfig.BlockSize; | |||
} | |||
paste.Content = content; | |||
paste.Title = title; | |||
paste.Syntax = syntax; | |||
paste.Hide = hide; | |||
return paste; | |||
} | |||
public static bool CheckExpiration(Models.Paste paste) | |||
{ | |||
if (paste.ExpireDate != null && DateTime.Now >= paste.ExpireDate) | |||
return true; | |||
if (paste.MaxViews > 0 && paste.Views > paste.MaxViews) | |||
return true; | |||
return false; | |||
} | |||
} | |||
} |
@@ -171,6 +171,7 @@ | |||
<Compile Include="Areas\Home\ViewModels\HomeViewModel.cs" /> | |||
<Compile Include="Areas\Paste\Controllers\PasteController.cs" /> | |||
<Compile Include="Areas\Paste\Models\Paste.cs" /> | |||
<Compile Include="Areas\Paste\PasteHelper.cs" /> | |||
<Compile Include="Areas\Paste\ViewModels\PasteCreateViewModel.cs" /> | |||
<Compile Include="Areas\Paste\PasteAreaRegistration.cs" /> | |||
<Compile Include="Areas\Paste\ViewModels\PasswordViewModel.cs" /> |