Browse Source

- Added robots.txt support

- Added models for API command parameters
- Fixed paste API not being able to have html inside the code content
- Added GetFullMessage for 500 errors and error emails.
tags/2.0.6
Teknikode 3 years ago
parent
commit
2afa02d6fe

+ 2
- 0
Teknik/App_Data/robots.txt View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: /

+ 54
- 53
Teknik/Areas/API/Controllers/APIv1Controller.cs View File

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

+ 17
- 0
Teknik/Areas/API/Models/APIv1BaseModel.cs View File

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

+ 37
- 0
Teknik/Areas/API/Models/APIv1PasteModel.cs View File

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

+ 17
- 0
Teknik/Areas/API/Models/APIv1ShortenModel.cs View File

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

+ 41
- 0
Teknik/Areas/API/Models/APIv1UploadModel.cs View File

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

+ 2
- 1
Teknik/Areas/Error/Controllers/ErrorController.cs View File

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


+ 3
- 1
Teknik/Areas/Error/Views/Error/Http500.cshtml View File

@@ -1,5 +1,7 @@
@model Teknik.Areas.Error.ViewModels.ErrorViewModel

@using Teknik.Helpers

<div class="container">
<div class="row">
<div class="col-md-12">
@@ -14,7 +16,7 @@
{
<div class="text-left">
<p>
<b>Exception:</b> @Model.Exception.Message
<b>Exception:</b> @Model.Exception.GetFullMessage(true)
<br />
<b>Source:</b> @Model.Exception.Source
</p>

+ 10
- 0
Teknik/Areas/Home/HomeAreaRegistration.cs View File

@@ -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<string>() { "*" }, // Subdomains
new List<string>() { 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

+ 10
- 0
Teknik/Controllers/DefaultController.cs View File

@@ -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()

+ 1
- 0
Teknik/Helpers/Constants.cs View File

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

+ 5
- 1
Teknik/Teknik.csproj View File

@@ -192,6 +192,10 @@
<Compile Include="Areas\API\APIAreaRegistration.cs" />
<Compile Include="Areas\API\Controllers\APIController.cs" />
<Compile Include="Areas\API\Controllers\APIv1Controller.cs" />
<Compile Include="Areas\API\Models\APIv1BaseModel.cs" />
<Compile Include="Areas\API\Models\APIv1PasteModel.cs" />
<Compile Include="Areas\API\Models\APIv1ShortenModel.cs" />
<Compile Include="Areas\API\Models\APIv1UploadModel.cs" />
<Compile Include="Areas\Blog\BlogAreaRegistration.cs" />
<Compile Include="Areas\Blog\Models\BlogPostComment.cs" />
<Compile Include="Areas\Blog\ViewModels\BlogViewModel.cs" />
@@ -345,6 +349,7 @@
<Content Include="App_Data\reservedUsernames.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="App_Data\robots.txt" />
<Content Include="Areas\Admin\Scripts\Search.js" />
<Content Include="Areas\Blog\Content\Blog.css" />
<Content Include="Areas\Blog\Scripts\Blog.js" />
@@ -665,7 +670,6 @@
<Folder Include="Areas\About\Views\Shared\" />
<Folder Include="Areas\Admin\Models\" />
<Folder Include="Areas\Admin\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\" />

Loading…
Cancel
Save