mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
- 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.
This commit is contained in:
parent
a253c61e74
commit
2afa02d6fe
2
Teknik/App_Data/robots.txt
Normal file
2
Teknik/App_Data/robots.txt
Normal file
@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow: /
|
@ -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);
|
||||
|
||||
db.Pastes.Add(paste);
|
||||
db.SaveChanges();
|
||||
|
||||
return Json(new
|
||||
if (model != null && model.code != null)
|
||||
{
|
||||
result = new
|
||||
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();
|
||||
|
||||
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
Teknik/Areas/API/Models/APIv1BaseModel.cs
Normal file
17
Teknik/Areas/API/Models/APIv1BaseModel.cs
Normal 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
Teknik/Areas/API/Models/APIv1PasteModel.cs
Normal file
37
Teknik/Areas/API/Models/APIv1PasteModel.cs
Normal 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
Teknik/Areas/API/Models/APIv1ShortenModel.cs
Normal file
17
Teknik/Areas/API/Models/APIv1ShortenModel.cs
Normal 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
Teknik/Areas/API/Models/APIv1UploadModel.cs
Normal file
41
Teknik/Areas/API/Models/APIv1UploadModel.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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…
Reference in New Issue
Block a user