diff --git a/Teknik/App_Data/robots.txt b/Teknik/App_Data/robots.txt new file mode 100644 index 0000000..c777a6b --- /dev/null +++ b/Teknik/App_Data/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/Teknik/Areas/API/Controllers/APIv1Controller.cs b/Teknik/Areas/API/Controllers/APIv1Controller.cs index 2542139..237103a 100644 --- a/Teknik/Areas/API/Controllers/APIv1Controller.cs +++ b/Teknik/Areas/API/Controllers/APIv1Controller.cs @@ -14,6 +14,7 @@ using System.Text; using Teknik.Areas.Shortener.Models; using nClam; using Teknik.Filters; +using Teknik.Areas.API.Models; namespace Teknik.Areas.API.Controllers { @@ -30,22 +31,21 @@ namespace Teknik.Areas.API.Controllers [HttpPost] [AllowAnonymous] [TrackPageView] - public ActionResult Upload(HttpPostedFileWrapper file, string contentType = null, bool encrypt = true, bool saveKey = true, string key = null, int keySize = 0, string iv = null, int blockSize = 0, bool genDeletionKey = false, bool doNotTrack = false) + public ActionResult Upload(APIv1UploadModel model) { try { - ViewBag.Title = "Upload"; - if (file != null) + if (model.file != null) { - if (file.ContentLength <= Config.UploadConfig.MaxUploadSize) + if (model.file.ContentLength <= Config.UploadConfig.MaxUploadSize) { // convert file to bytes byte[] fileData = null; - string fileExt = Path.GetExtension(file.FileName); - int contentLength = file.ContentLength; - using (var binaryReader = new BinaryReader(file.InputStream)) + string fileExt = Path.GetExtension(model.file.FileName); + int contentLength = model.file.ContentLength; + using (var binaryReader = new BinaryReader(model.file.InputStream)) { - fileData = binaryReader.ReadBytes(file.ContentLength); + fileData = binaryReader.ReadBytes(model.file.ContentLength); } // Scan the file to detect a virus @@ -53,13 +53,13 @@ namespace Teknik.Areas.API.Controllers { byte[] scanData = fileData; // If it was encrypted client side, decrypt it - if (!encrypt && key != null) + if (!model.encrypt && model.key != null) { // If the IV is set, and Key is set, then decrypt it - if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(iv)) + if (!string.IsNullOrEmpty(model.key) && !string.IsNullOrEmpty(model.iv)) { // Decrypt the data - scanData = AES.Decrypt(scanData, key, iv); + scanData = AES.Decrypt(scanData, model.key, model.iv); } } ClamClient clam = new ClamClient(Config.UploadConfig.ClamServer, Config.UploadConfig.ClamPort); @@ -80,32 +80,32 @@ namespace Teknik.Areas.API.Controllers } // Need to grab the contentType if it's empty - if (string.IsNullOrEmpty(contentType)) + if (string.IsNullOrEmpty(model.contentType)) { - contentType = (string.IsNullOrEmpty(file.ContentType)) ? "application/octet-stream" : file.ContentType; + model.contentType = (string.IsNullOrEmpty(model.file.ContentType)) ? "application/octet-stream" : model.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; + if (model.keySize <= 0) + model.keySize = Config.UploadConfig.KeySize; + if (model.blockSize <= 0) + model.blockSize = Config.UploadConfig.BlockSize; byte[] data = null; // If they want us to encrypt the file first, do that here - if (encrypt) + if (model.encrypt) { // Generate key and iv if empty - if (string.IsNullOrEmpty(key)) + if (string.IsNullOrEmpty(model.key)) { - key = Utility.RandomString(keySize / 8); + model.key = Utility.RandomString(model.keySize / 8); } - if (string.IsNullOrEmpty(iv)) + if (string.IsNullOrEmpty(model.iv)) { - iv = Utility.RandomString(blockSize / 8); + model.iv = Utility.RandomString(model.blockSize / 8); } - data = AES.Encrypt(fileData, key, iv); + data = AES.Encrypt(fileData, model.key, model.iv); if (data == null || data.Length <= 0) { return Json(new { error = new { message = "Unable to encrypt file" } }); @@ -113,12 +113,12 @@ namespace Teknik.Areas.API.Controllers } // Save the file data - Upload.Models.Upload upload = Uploader.SaveFile(db, Config, (encrypt) ? data : fileData, contentType, contentLength, fileExt, iv, (saveKey) ? key : null, keySize, blockSize); + Upload.Models.Upload upload = Uploader.SaveFile(db, Config, (model.encrypt) ? data : fileData, model.contentType, contentLength, fileExt, model.iv, (model.saveKey) ? model.key : null, model.keySize, model.blockSize); if (upload != null) { // Generate delete key if asked to - if (genDeletionKey) + if (model.genDeletionKey) { string delKey = Utility.RandomString(Config.UploadConfig.DeleteKeyLength); upload.DeleteKey = delKey; @@ -130,14 +130,14 @@ namespace Teknik.Areas.API.Controllers string fullUrl = Url.SubRouteUrl("upload", "Upload.Download", new { file = upload.Url }); var returnData = new { - url = (saveKey || string.IsNullOrEmpty(key)) ? fullUrl : fullUrl + "#" + key, + url = (model.saveKey || string.IsNullOrEmpty(model.key)) ? fullUrl : fullUrl + "#" + model.key, fileName = upload.Url, - contentType = contentType, + contentType = model.contentType, contentLength = contentLength, - key = key, - keySize = keySize, - iv = iv, - blockSize = blockSize, + key = model.key, + keySize = model.keySize, + iv = model.iv, + blockSize = model.blockSize, deletionKey = upload.DeleteKey }; @@ -150,7 +150,6 @@ namespace Teknik.Areas.API.Controllers return Json(new { error = new { message = "File Too Large" } }); } } - return Json(new { error = new { message = "Invalid Upload Request" } }); } catch(Exception ex) @@ -162,28 +161,31 @@ namespace Teknik.Areas.API.Controllers [HttpPost] [AllowAnonymous] [TrackPageView] - public ActionResult Paste(string code, string title = "", string syntax = "text", string expireUnit = "never", int expireLength = 1, string password = "", bool hide = false, bool doNotTrack = false) + public ActionResult Paste(APIv1PasteModel model) { try { - ViewBag.Title = "Paste"; - Paste.Models.Paste paste = PasteHelper.CreatePaste(code, title, syntax, expireUnit, expireLength, password, hide); + if (model != null && model.code != null) + { + Paste.Models.Paste paste = PasteHelper.CreatePaste(model.code, model.title, model.syntax, model.expireUnit, model.expireLength, model.password, model.hide); - db.Pastes.Add(paste); - db.SaveChanges(); + db.Pastes.Add(paste); + db.SaveChanges(); - return Json(new - { - result = new + return Json(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 - } - }); + result = new + { + id = paste.Url, + url = Url.SubRouteUrl("paste", "Paste.View", new { type = "Full", url = paste.Url, password = model.password }), + title = paste.Title, + syntax = paste.Syntax, + expiration = paste.ExpireDate, + password = model.password + } + }); + } + return Json(new { error = new { message = "Invalid Paste Request" } }); } catch (Exception ex) { @@ -194,14 +196,13 @@ namespace Teknik.Areas.API.Controllers [HttpPost] [AllowAnonymous] [TrackPageView] - public ActionResult Shorten(string url, bool doNotTrack = false) + public ActionResult Shorten(APIv1ShortenModel model) { try { - ViewBag.Title = "Shorten"; - if (url.IsValidUrl()) + if (model.url.IsValidUrl()) { - ShortenedUrl newUrl = Shortener.Shortener.ShortenUrl(url, Config.ShortenerConfig.UrlLength); + ShortenedUrl newUrl = Shortener.Shortener.ShortenUrl(model.url, Config.ShortenerConfig.UrlLength); db.ShortenedUrls.Add(newUrl); db.SaveChanges(); @@ -217,7 +218,7 @@ namespace Teknik.Areas.API.Controllers result = new { shortUrl = shortUrl, - originalUrl = url + originalUrl = model.url } }); } diff --git a/Teknik/Areas/API/Models/APIv1BaseModel.cs b/Teknik/Areas/API/Models/APIv1BaseModel.cs new file mode 100644 index 0000000..ab231ec --- /dev/null +++ b/Teknik/Areas/API/Models/APIv1BaseModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Teknik.Areas.API.Models +{ + public class APIv1BaseModel + { + public bool doNotTrack { get; set; } + + public APIv1BaseModel() + { + doNotTrack = false; + } + } +} \ No newline at end of file diff --git a/Teknik/Areas/API/Models/APIv1PasteModel.cs b/Teknik/Areas/API/Models/APIv1PasteModel.cs new file mode 100644 index 0000000..f743388 --- /dev/null +++ b/Teknik/Areas/API/Models/APIv1PasteModel.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace Teknik.Areas.API.Models +{ + public class APIv1PasteModel : APIv1BaseModel + { + [AllowHtml] + public string code { get; set; } + + public string title { get; set; } + + public string syntax { get; set; } + + public string expireUnit { get; set; } + + public int expireLength { get; set; } + + public string password { get; set; } + + public bool hide { get; set; } + + public APIv1PasteModel() + { + code = null; + title = string.Empty; + syntax = "text"; + expireUnit = "never"; + expireLength = 1; + password = string.Empty; + hide = false; + } + } +} \ No newline at end of file diff --git a/Teknik/Areas/API/Models/APIv1ShortenModel.cs b/Teknik/Areas/API/Models/APIv1ShortenModel.cs new file mode 100644 index 0000000..6eaf7ab --- /dev/null +++ b/Teknik/Areas/API/Models/APIv1ShortenModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Teknik.Areas.API.Models +{ + public class APIv1ShortenModel : APIv1BaseModel + { + public string url { get; set; } + + public APIv1ShortenModel() + { + url = string.Empty; + } + } +} \ No newline at end of file diff --git a/Teknik/Areas/API/Models/APIv1UploadModel.cs b/Teknik/Areas/API/Models/APIv1UploadModel.cs new file mode 100644 index 0000000..e9e8000 --- /dev/null +++ b/Teknik/Areas/API/Models/APIv1UploadModel.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Teknik.Areas.API.Models +{ + public class APIv1UploadModel : APIv1BaseModel + { + public HttpPostedFileWrapper file { get; set; } + + public string contentType { get; set; } + + public bool encrypt { get; set; } + + public bool saveKey { get; set; } + + public string key { get; set; } + + public int keySize { get; set; } + + public string iv { get; set; } + + public int blockSize { get; set; } + + public bool genDeletionKey { get; set; } + + public APIv1UploadModel() + { + file = null; + contentType = null; + encrypt = true; + saveKey = true; + key = null; + keySize = 0; + iv = null; + blockSize = 0; + genDeletionKey = false; + } + } +} \ No newline at end of file diff --git a/Teknik/Areas/Error/Controllers/ErrorController.cs b/Teknik/Areas/Error/Controllers/ErrorController.cs index 11c8187..6b33c4c 100644 --- a/Teknik/Areas/Error/Controllers/ErrorController.cs +++ b/Teknik/Areas/Error/Controllers/ErrorController.cs @@ -8,6 +8,7 @@ using System.Web.Mvc; using Teknik.Areas.Error.ViewModels; using Teknik.Controllers; using Teknik.Filters; +using Teknik.Helpers; namespace Teknik.Areas.Error.Controllers { @@ -148,7 +149,7 @@ Message: {0} Source: {1} -Stack Trace: {2}", ex.Message, ex.Source, ex.StackTrace); +Stack Trace: {2}", ex.GetFullMessage(true), ex.Source, ex.StackTrace); mail.BodyEncoding = UTF8Encoding.UTF8; mail.DeliveryNotificationOptions = DeliveryNotificationOptions.Never; diff --git a/Teknik/Areas/Error/Views/Error/Http500.cshtml b/Teknik/Areas/Error/Views/Error/Http500.cshtml index cf5bb5f..2e4a84d 100644 --- a/Teknik/Areas/Error/Views/Error/Http500.cshtml +++ b/Teknik/Areas/Error/Views/Error/Http500.cshtml @@ -1,5 +1,7 @@ @model Teknik.Areas.Error.ViewModels.ErrorViewModel +@using Teknik.Helpers +
@@ -14,7 +16,7 @@ {

- Exception: @Model.Exception.Message + Exception: @Model.Exception.GetFullMessage(true)
Source: @Model.Exception.Source

diff --git a/Teknik/Areas/Home/HomeAreaRegistration.cs b/Teknik/Areas/Home/HomeAreaRegistration.cs index b3db738..a78f096 100644 --- a/Teknik/Areas/Home/HomeAreaRegistration.cs +++ b/Teknik/Areas/Home/HomeAreaRegistration.cs @@ -42,6 +42,16 @@ namespace Teknik.Areas.Home new[] { typeof(DefaultController).Namespace } ); + // Handle robots.txt file requests + context.MapSubdomainRoute( + "Default.Robots", // Route name + new List() { "*" }, // Subdomains + new List() { config.Host, config.ShortenerConfig.ShortenerHost }, // domains + "robots.txt", // URL with parameters + new { controller = "Default", action = "Robots" }, // Parameter defaults + new[] { typeof(DefaultController).Namespace } + ); + // Register fallback for all bad requests context.MapSubdomainRoute( "Default.NotFound", // Route name diff --git a/Teknik/Controllers/DefaultController.cs b/Teknik/Controllers/DefaultController.cs index 134093a..d67141c 100644 --- a/Teknik/Controllers/DefaultController.cs +++ b/Teknik/Controllers/DefaultController.cs @@ -68,6 +68,16 @@ namespace Teknik.Controllers return File(imageFile, "image/svg+xml"); } + // Get the Logo + [HttpGet] + [AllowAnonymous] + public ActionResult Robots() + { + // Get favicon + string file = Server.MapPath(Constants.ROBOTS_PATH); + return File(file, "plain/text"); + } + [HttpGet] [AllowAnonymous] public ActionResult NotFound() diff --git a/Teknik/Helpers/Constants.cs b/Teknik/Helpers/Constants.cs index 406b9bd..b14550e 100644 --- a/Teknik/Helpers/Constants.cs +++ b/Teknik/Helpers/Constants.cs @@ -13,5 +13,6 @@ namespace Teknik.Helpers public const string TRUSTEDDEVICECOOKIE = "TeknikTrustedDevice"; public const string LOGO_PATH = "~/Images/logo-black.svg"; public const string FAVICON_PATH = "~/Images/favicon.ico"; + public const string ROBOTS_PATH = "~/App_Data/robots.txt"; } } diff --git a/Teknik/Teknik.csproj b/Teknik/Teknik.csproj index a71033e..1111ff1 100644 --- a/Teknik/Teknik.csproj +++ b/Teknik/Teknik.csproj @@ -192,6 +192,10 @@ + + + + @@ -345,6 +349,7 @@ Always + @@ -665,7 +670,6 @@ -