1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

Added ability to set expirations for uploads. Includes default settings for logged in users.

This commit is contained in:
Uncled1023 2019-01-16 23:58:10 -08:00
parent 065ff3ed05
commit 416387c764
20 changed files with 1954 additions and 65 deletions

View File

@ -41,11 +41,14 @@ namespace Teknik.Areas.API.V1.Controllers
if (User.Identity.IsAuthenticated)
{
maxUploadSize = _config.UploadConfig.MaxUploadSizeBasic;
User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
//if (user.AccountType == AccountType.Premium)
//{
// maxUploadSize = _config.UploadConfig.MaxUploadSizePremium;
//}
if (User.Identity.IsAuthenticated)
{
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
if (userInfo.AccountType == AccountType.Premium)
{
maxUploadSize = _config.UploadConfig.MaxUploadSizePremium;
}
}
}
if (model.file.Length <= maxUploadSize)
{
@ -110,7 +113,7 @@ namespace Teknik.Areas.API.V1.Controllers
model.blockSize = _config.UploadConfig.BlockSize;
// Save the file data
Upload.Models.Upload upload = Uploader.SaveFile(_dbContext, _config, model.file.OpenReadStream(), model.contentType, contentLength, model.encrypt, fileExt, model.iv, model.key, model.keySize, model.blockSize);
Upload.Models.Upload upload = UploadHelper.SaveFile(_dbContext, _config, model.file.OpenReadStream(), model.contentType, contentLength, model.encrypt, model.expirationUnit, model.expirationLength, fileExt, model.iv, model.key, model.keySize, model.blockSize);
if (upload != null)
{

View File

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Utilities;
namespace Teknik.Areas.API.V1.Models
{
@ -14,6 +15,10 @@ namespace Teknik.Areas.API.V1.Models
public bool encrypt { get; set; }
public int expirationLength { get; set; }
public ExpirationUnit expirationUnit { get; set; }
public bool saveKey { get; set; }
public string key { get; set; }
@ -31,6 +36,8 @@ namespace Teknik.Areas.API.V1.Models
file = null;
contentType = null;
encrypt = true;
expirationLength = 1;
expirationUnit = ExpirationUnit.Never;
saveKey = true;
key = null;
keySize = 0;

View File

@ -42,6 +42,8 @@ namespace Teknik.Areas.Upload.Controllers
if (user != null)
{
model.Encrypt = user.UploadSettings.Encrypt;
model.ExpirationLength = user.UploadSettings.ExpirationLength;
model.ExpirationUnit = user.UploadSettings.ExpirationUnit;
model.Vaults = user.Vaults.ToList();
}
else
@ -54,7 +56,7 @@ namespace Teknik.Areas.Upload.Controllers
[HttpPost]
[AllowAnonymous]
[DisableRequestSizeLimit]
public async Task<IActionResult> Upload(string fileType, string fileExt, string iv, int keySize, int blockSize, bool encrypt, IFormFile file)
public async Task<IActionResult> Upload([FromForm] UploadFileViewModel uploadFile)
{
try
{
@ -73,15 +75,15 @@ namespace Teknik.Areas.Upload.Controllers
}
}
}
if (file.Length <= maxUploadSize)
if (uploadFile.file.Length <= maxUploadSize)
{
// convert file to bytes
long contentLength = file.Length;
long contentLength = uploadFile.file.Length;
// Scan the file to detect a virus
if (_config.UploadConfig.VirusScanEnable)
{
using (Stream fs = file.OpenReadStream())
using (Stream fs = uploadFile.file.OpenReadStream())
{
ClamClient clam = new ClamClient(_config.UploadConfig.ClamServer, _config.UploadConfig.ClamPort);
clam.MaxStreamSize = maxUploadSize;
@ -102,17 +104,28 @@ namespace Teknik.Areas.Upload.Controllers
}
// Check content type restrictions (Only for encrypting server side
if (encrypt)
if (!uploadFile.options.Encrypt)
{
if (_config.UploadConfig.RestrictedContentTypes.Contains(fileType) || _config.UploadConfig.RestrictedExtensions.Contains(fileExt))
if (_config.UploadConfig.RestrictedContentTypes.Contains(uploadFile.fileType) || _config.UploadConfig.RestrictedExtensions.Contains(uploadFile.fileExt))
{
return Json(new { error = new { message = "File Type Not Allowed" } });
}
}
using (Stream fs = file.OpenReadStream())
using (Stream fs = uploadFile.file.OpenReadStream())
{
Models.Upload upload = Uploader.SaveFile(_dbContext, _config, fs, fileType, contentLength, encrypt, fileExt, iv, null, keySize, blockSize);
Models.Upload upload = UploadHelper.SaveFile(_dbContext,
_config,
fs,
uploadFile.fileType,
contentLength,
!uploadFile.options.Encrypt,
uploadFile.options.ExpirationUnit,
uploadFile.options.ExpirationLength,
uploadFile.fileExt,
uploadFile.iv, null,
uploadFile.keySize,
uploadFile.blockSize);
if (upload != null)
{
if (User.Identity.IsAuthenticated)
@ -160,28 +173,36 @@ namespace Teknik.Areas.Upload.Controllers
bool premiumAccount = false;
DateTime dateUploaded = new DateTime();
Models.Upload uploads = _dbContext.Uploads.Where(up => up.Url == file).FirstOrDefault();
if (uploads != null)
Models.Upload upload = _dbContext.Uploads.Where(up => up.Url == file).FirstOrDefault();
if (upload != null)
{
uploads.Downloads += 1;
_dbContext.Entry(uploads).State = EntityState.Modified;
// Check Expiration
if (UploadHelper.CheckExpiration(upload))
{
_dbContext.Uploads.Remove(upload);
_dbContext.SaveChanges();
return new StatusCodeResult(StatusCodes.Status404NotFound);
}
upload.Downloads += 1;
_dbContext.Entry(upload).State = EntityState.Modified;
_dbContext.SaveChanges();
fileName = uploads.FileName;
url = uploads.Url;
key = uploads.Key;
iv = uploads.IV;
contentType = uploads.ContentType;
contentLength = uploads.ContentLength;
dateUploaded = uploads.DateUploaded;
fileName = upload.FileName;
url = upload.Url;
key = upload.Key;
iv = upload.IV;
contentType = upload.ContentType;
contentLength = upload.ContentLength;
dateUploaded = upload.DateUploaded;
if (User.Identity.IsAuthenticated)
{
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, User.Identity.Name);
premiumAccount = userInfo.AccountType == AccountType.Premium;
}
if (!premiumAccount && uploads.User != null)
if (!premiumAccount && upload.User != null)
{
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, uploads.User.Username);
IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(_config, upload.User.Username);
premiumAccount = userInfo.AccountType == AccountType.Premium;
}
}
@ -375,6 +396,14 @@ namespace Teknik.Areas.Upload.Controllers
Models.Upload upload = _dbContext.Uploads.Where(up => up.Url == file).FirstOrDefault();
if (upload != null)
{
// Check Expiration
if (UploadHelper.CheckExpiration(upload))
{
_dbContext.Uploads.Remove(upload);
_dbContext.SaveChanges();
return Json(new { error = new { message = "File Does Not Exist" } });
}
string subDir = upload.FileName[0].ToString();
string filePath = Path.Combine(_config.UploadConfig.UploadDirectory, subDir, upload.FileName);
if (System.IO.File.Exists(filePath))

View File

@ -12,28 +12,29 @@ using Teknik.Data;
namespace Teknik.Areas.Upload
{
public static class Uploader
public static class UploadHelper
{
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt)
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, string.Empty, null, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, string fileExt)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, fileExt, null, null, 256, 128);
return SaveFile(db, config, file, contentType, contentLength, encrypt, expirationUnit, expirationLength, string.Empty, null, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, string fileExt, string iv)
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength, string fileExt)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, fileExt, iv, null, 256, 128);
return SaveFile(db, config, file, contentType, contentLength, encrypt, expirationUnit, expirationLength, fileExt, null, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, string fileExt, string iv, string key)
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength, string fileExt, string iv)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, fileExt, iv, key, 256, 128);
return SaveFile(db, config, file, contentType, contentLength, encrypt, expirationUnit, expirationLength, fileExt, iv, null, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, string fileExt, string iv, string key, int keySize, int blockSize)
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength, string fileExt, string iv, string key)
{
return SaveFile(db, config, file, contentType, contentLength, encrypt, expirationUnit, expirationLength, fileExt, iv, key, 256, 128);
}
public static Models.Upload SaveFile(TeknikEntities db, Config config, Stream file, string contentType, long contentLength, bool encrypt, ExpirationUnit expirationUnit, int expirationLength, string fileExt, string iv, string key, int keySize, int blockSize)
{
if (!Directory.Exists(config.UploadConfig.UploadDirectory))
{
@ -93,10 +94,46 @@ namespace Teknik.Areas.Upload
upload.BlockSize = blockSize;
upload.DeleteKey = delKey;
if (expirationUnit == ExpirationUnit.Views)
{
upload.MaxDownloads = expirationLength;
}
else
{
switch (expirationUnit)
{
case ExpirationUnit.Minutes:
upload.ExpireDate = DateTime.Now.AddMinutes(expirationLength);
break;
case ExpirationUnit.Hours:
upload.ExpireDate = DateTime.Now.AddHours(expirationLength);
break;
case ExpirationUnit.Days:
upload.ExpireDate = DateTime.Now.AddDays(expirationLength);
break;
case ExpirationUnit.Months:
upload.ExpireDate = DateTime.Now.AddMonths(expirationLength);
break;
case ExpirationUnit.Years:
upload.ExpireDate = DateTime.Now.AddYears(expirationLength);
break;
}
}
db.Uploads.Add(upload);
db.SaveChanges();
return upload;
}
public static bool CheckExpiration(Models.Upload upload)
{
if (upload.ExpireDate != null && DateTime.Now >= upload.ExpireDate)
return true;
if (upload.MaxDownloads > 0 && upload.Downloads >= upload.MaxDownloads)
return true;
return false;
}
}
}

View File

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Teknik.Areas.Users.Models;
using Teknik.Utilities;
namespace Teknik.Areas.Upload.ViewModels
{
public class UploadFileViewModel
{
public string fileType { get; set; }
public string fileExt { get; set; }
public string iv { get; set; }
public int keySize { get; set; }
public int blockSize { get; set; }
[ModelBinder(BinderType = typeof(FormDataJsonBinder))]
public UploadSettings options { get; set; }
public IFormFile file { get; set; }
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Utilities;
using Teknik.ViewModels;
namespace Teknik.Areas.Upload.ViewModels
@ -12,12 +13,18 @@ namespace Teknik.Areas.Upload.ViewModels
public bool Encrypt { get; set; }
public int ExpirationLength { get; set; }
public ExpirationUnit ExpirationUnit { get; set; }
public List<Vault.Models.Vault> Vaults { get; set; }
public UploadViewModel()
{
CurrentSub = string.Empty;
Encrypt = false;
ExpirationLength = 1;
ExpirationUnit = ExpirationUnit.Never;
Vaults = new List<Vault.Models.Vault>();
}
}

View File

@ -30,7 +30,7 @@
<div class="container">
<div class="row text-center">
<div class="col-sm-8 col-sm-offset-2">
<div class="col-sm-10 col-sm-offset-1">
<div class="row text-center">
<div class="well well-lg text-center" id="uploadButton" style="cursor: pointer">
<div class="row">
@ -51,13 +51,8 @@
</div>
</div>
</div>
<div class="col-sm-2">
<div class="row">
<div class="col-sm-12">
<label for="encrypt">Encrypt in Browser</label>
<input type="checkbox" name="encrypt" id="encrypt" @(Model.Encrypt ? "checked" : string.Empty) />
</div>
</div>
<div class="col-sm-1">
<button type="button" class="btn btn-default btn-sm" data-toggle="modal" data-target="#uploadSettings"><i class="fa fa-gear"></i></button>
</div>
</div>
<div class="row" id="upload-action-buttons" style="display: none">
@ -97,6 +92,49 @@
</div>
</div>
<div class="modal fade" id="uploadSettings" tabindex="-1" role="dialog" aria-labelledby="uploadSettingsLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="row">
<div class="col-sm-6">
<div class="row">
<div class="col-sm-12 text-center">
<h4 class="text-center">Encrypt in Browser</h4>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<input type="checkbox" class="center-block" name="encrypt" id="encrypt" @(Model.Encrypt ? "checked" : string.Empty) />
</div>
</div>
</div>
<div class="col-sm-6">
<div class="row">
<div class="col-sm-12 text-center">
<h4 class="text-center">Expiration</h4>
</div>
</div>
<div class="row">
<div class="col-sm-4 hidden" id="length-div">
<input type="number" min="1" step="1" class="form-control" name="expirelength" id="expirelength" value="@Model.ExpirationLength">
</div>
<div class="col-sm-12" id="unit-div">
<select class="form-control" name="expireunit" id="expireunit">
@foreach (ExpirationUnit unit in Enum.GetValues(typeof(ExpirationUnit)))
{
<!option value="@unit" @(Model.ExpirationUnit == unit ? "selected" : string.Empty)>@unit.ToString()</!option>
}
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="templates" style="display: none">
<div class="row" id="upload-template">
<div class="col-sm-12">
@ -113,13 +151,15 @@
<div class="row" id="upload-link-panel">
<input type="hidden" id="upload-url" />
<div class="col-sm-8">
<dl class="dl-horizontal">
<dl class="dl-horizontal" style="margin-bottom: 0;">
<dt>Url</dt>
<dd><a href="#" id="upload-link" target="_blank" class="alert-link"></a></dd>
<dt>Content-Type</dt>
<dd id="upload-contentType"></dd>
<dt>File Size</dt>
<dd id="upload-contentLength"></dd>
<dt>Expiration</dt>
<dd id="upload-expiration"></dd>
</dl>
</div>
<div class="col-sm-4">

View File

@ -574,6 +574,8 @@ namespace Teknik.Areas.Users.Controllers
model.UserID = user.UserId;
model.Username = user.Username;
model.Encrypt = user.UploadSettings.Encrypt;
model.ExpirationLength = user.UploadSettings.ExpirationLength;
model.ExpirationUnit = user.UploadSettings.ExpirationUnit;
return View("/Areas/User/Views/User/Settings/UploadSettings.cshtml", model);
}
@ -732,6 +734,8 @@ namespace Teknik.Areas.Users.Controllers
{
// Profile Info
user.UploadSettings.Encrypt = settings.Encrypt;
user.UploadSettings.ExpirationUnit = settings.ExpirationUnit;
user.UploadSettings.ExpirationLength = settings.ExpirationLength;
UserHelper.EditAccount(_dbContext, _config, user);
return Json(new { result = true });

View File

@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teknik.Utilities;
namespace Teknik.Areas.Users.Models
{
@ -13,9 +14,17 @@ namespace Teknik.Areas.Users.Models
[Column("Encrypt")]
public bool Encrypt { get; set; }
[Column("ExpirationLength")]
public int ExpirationLength { get; set; }
[Column("ExpirationUnit")]
public ExpirationUnit ExpirationUnit { get; set; }
public UploadSettings()
{
Encrypt = false;
ExpirationLength = 1;
ExpirationUnit = ExpirationUnit.Never;
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Areas.Users.Models;
using Teknik.Utilities;
using Teknik.ViewModels;
namespace Teknik.Areas.Users.ViewModels
@ -10,10 +11,14 @@ namespace Teknik.Areas.Users.ViewModels
public class UploadSettingsViewModel : SettingsViewModel
{
public bool Encrypt { get; set; }
public int ExpirationLength { get; set; }
public ExpirationUnit ExpirationUnit { get; set; }
public UploadSettingsViewModel()
{
Encrypt = false;
ExpirationLength = 1;
ExpirationUnit = ExpirationUnit.Never;
}
}
}

View File

@ -22,6 +22,26 @@
</label>
</div>
</div>
<div class="col-sm-6">
<div class="row">
<div class="col-sm-12 text-center">
<h4 class="text-center">Expiration</h4>
</div>
</div>
<div class="row">
<div class="col-sm-4 hidden" id="length-div">
<input type="number" min="1" step="1" class="form-control" name="expirelength" id="expirelength" value="@Model.ExpirationLength">
</div>
<div class="col-sm-12" id="unit-div">
<select class="form-control" name="expireunit" id="expireunit">
@foreach (ExpirationUnit unit in Enum.GetValues(typeof(ExpirationUnit)))
{
<!option value="@unit" @(Model.ExpirationUnit == unit ? "selected" : string.Empty)>@unit.ToString()</!option>
}
</select>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-sm-10">

View File

@ -0,0 +1,749 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Teknik.Data;
namespace Teknik.Data.Migrations
{
[DbContext(typeof(TeknikEntities))]
[Migration("20190116060104_UploadExpirationSettings")]
partial class UploadExpirationSettings
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.2.0-preview3-35497")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Teknik.Areas.Blog.Models.Blog", b =>
{
b.Property<int>("BlogId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("UserId");
b.HasKey("BlogId");
b.HasIndex("UserId");
b.ToTable("Blogs");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPost", b =>
{
b.Property<int>("BlogPostId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Article");
b.Property<int>("BlogId");
b.Property<DateTime>("DateEdited");
b.Property<DateTime>("DatePosted");
b.Property<DateTime>("DatePublished");
b.Property<bool>("Published");
b.Property<bool>("System");
b.Property<string>("Title");
b.HasKey("BlogPostId");
b.HasIndex("BlogId");
b.ToTable("BlogPosts");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostComment", b =>
{
b.Property<int>("BlogPostCommentId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Article");
b.Property<int>("BlogPostId");
b.Property<DateTime>("DateEdited");
b.Property<DateTime>("DatePosted");
b.Property<int?>("UserId");
b.HasKey("BlogPostCommentId");
b.HasIndex("BlogPostId");
b.HasIndex("UserId");
b.ToTable("BlogPostComments");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostTag", b =>
{
b.Property<int>("BlogPostTagId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("BlogPostId");
b.Property<string>("Description");
b.Property<string>("Name");
b.HasKey("BlogPostTagId");
b.HasIndex("BlogPostId");
b.ToTable("BlogPostTags");
});
modelBuilder.Entity("Teknik.Areas.Contact.Models.Contact", b =>
{
b.Property<int>("ContactId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateAdded");
b.Property<string>("Email");
b.Property<string>("Message");
b.Property<string>("Name");
b.Property<string>("Subject");
b.HasKey("ContactId");
b.ToTable("Contact");
});
modelBuilder.Entity("Teknik.Areas.Paste.Models.Paste", b =>
{
b.Property<int>("PasteId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("BlockSize");
b.Property<string>("Content");
b.Property<DateTime>("DatePosted");
b.Property<string>("DeleteKey")
.HasAnnotation("CaseSensitive", true);
b.Property<DateTime?>("ExpireDate");
b.Property<string>("FileName")
.HasAnnotation("CaseSensitive", true);
b.Property<string>("HashedPassword")
.HasAnnotation("CaseSensitive", true);
b.Property<bool>("Hide");
b.Property<string>("IV")
.HasAnnotation("CaseSensitive", true);
b.Property<string>("Key")
.HasAnnotation("CaseSensitive", true);
b.Property<int>("KeySize");
b.Property<int>("MaxViews");
b.Property<string>("Syntax");
b.Property<string>("Title");
b.Property<string>("Url")
.HasAnnotation("CaseSensitive", true);
b.Property<int?>("UserId");
b.Property<int>("Views");
b.HasKey("PasteId");
b.HasIndex("UserId");
b.ToTable("Pastes");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.Podcast", b =>
{
b.Property<int>("PodcastId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateEdited");
b.Property<DateTime>("DatePosted");
b.Property<DateTime>("DatePublished");
b.Property<string>("Description");
b.Property<int>("Episode");
b.Property<bool>("Published");
b.Property<string>("Title");
b.HasKey("PodcastId");
b.ToTable("Podcasts");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastComment", b =>
{
b.Property<int>("PodcastCommentId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Article");
b.Property<DateTime>("DateEdited");
b.Property<DateTime>("DatePosted");
b.Property<int>("PodcastId");
b.Property<int>("UserId");
b.HasKey("PodcastCommentId");
b.HasIndex("PodcastId");
b.HasIndex("UserId");
b.ToTable("PodcastComments");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastFile", b =>
{
b.Property<int>("PodcastFileId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<long>("ContentLength");
b.Property<string>("ContentType");
b.Property<string>("FileName");
b.Property<string>("Path");
b.Property<int>("PodcastId");
b.Property<int>("Size");
b.HasKey("PodcastFileId");
b.HasIndex("PodcastId");
b.ToTable("PodcastFiles");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastTag", b =>
{
b.Property<int>("PodcastTagId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Description");
b.Property<string>("Name");
b.Property<int>("PodcastId");
b.HasKey("PodcastTagId");
b.HasIndex("PodcastId");
b.ToTable("PodcastTags");
});
modelBuilder.Entity("Teknik.Areas.Shortener.Models.ShortenedUrl", b =>
{
b.Property<int>("ShortenedUrlId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateAdded");
b.Property<string>("OriginalUrl");
b.Property<string>("ShortUrl")
.HasAnnotation("CaseSensitive", true);
b.Property<int?>("UserId");
b.Property<int>("Views");
b.HasKey("ShortenedUrlId");
b.HasIndex("UserId");
b.ToTable("ShortenedUrls");
});
modelBuilder.Entity("Teknik.Areas.Stats.Models.Takedown", b =>
{
b.Property<int>("TakedownId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ActionTaken");
b.Property<DateTime>("DateActionTaken");
b.Property<DateTime>("DateRequested");
b.Property<string>("Reason");
b.Property<string>("Requester");
b.Property<string>("RequesterContact");
b.HasKey("TakedownId");
b.ToTable("Takedowns");
});
modelBuilder.Entity("Teknik.Areas.Stats.Models.Transaction", b =>
{
b.Property<int>("TransactionId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<decimal>("Amount")
.HasColumnType("decimal(19, 5)");
b.Property<int>("Currency");
b.Property<DateTime>("DateSent");
b.Property<string>("Reason");
b.HasKey("TransactionId");
b.ToTable("Transactions");
});
modelBuilder.Entity("Teknik.Areas.Upload.Models.Upload", b =>
{
b.Property<int>("UploadId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("BlockSize");
b.Property<long>("ContentLength");
b.Property<string>("ContentType");
b.Property<DateTime>("DateUploaded");
b.Property<string>("DeleteKey")
.HasAnnotation("CaseSensitive", true);
b.Property<int>("Downloads");
b.Property<DateTime?>("ExpireDate");
b.Property<string>("FileName")
.HasAnnotation("CaseSensitive", true);
b.Property<string>("IV")
.HasAnnotation("CaseSensitive", true);
b.Property<string>("Key")
.HasAnnotation("CaseSensitive", true);
b.Property<int>("KeySize");
b.Property<int>("MaxDownloads");
b.Property<int?>("Takedown_TakedownId");
b.Property<string>("Url")
.HasAnnotation("CaseSensitive", true);
b.Property<int?>("UserId");
b.HasKey("UploadId");
b.HasIndex("Takedown_TakedownId");
b.HasIndex("UserId");
b.ToTable("Uploads");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.InviteCode", b =>
{
b.Property<int>("InviteCodeId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<bool>("Active");
b.Property<int?>("ClaimedUserId");
b.Property<string>("Code")
.HasAnnotation("CaseSensitive", true);
b.Property<int?>("OwnerId");
b.HasKey("InviteCodeId");
b.HasIndex("ClaimedUserId")
.IsUnique()
.HasFilter("[ClaimedUserId] IS NOT NULL");
b.HasIndex("OwnerId");
b.ToTable("InviteCodes");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.LoginInfo", b =>
{
b.Property<int>("LoginInfoId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("LoginProvider");
b.Property<string>("ProviderDisplayName");
b.Property<string>("ProviderKey");
b.Property<int>("UserId");
b.HasKey("LoginInfoId");
b.HasIndex("UserId");
b.ToTable("UserLogins");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.User", b =>
{
b.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Username");
b.HasKey("UserId");
b.ToTable("Users");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.Vault", b =>
{
b.Property<int>("VaultId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateCreated");
b.Property<DateTime>("DateEdited");
b.Property<string>("Description");
b.Property<string>("Title");
b.Property<string>("Url");
b.Property<int?>("UserId");
b.Property<int>("Views");
b.HasKey("VaultId");
b.HasIndex("UserId");
b.ToTable("Vaults");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.VaultItem", b =>
{
b.Property<int>("VaultItemId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateAdded");
b.Property<string>("Description");
b.Property<string>("Discriminator")
.IsRequired();
b.Property<string>("Title");
b.Property<int>("VaultId");
b.HasKey("VaultItemId");
b.HasIndex("VaultId");
b.ToTable("VaultItems");
b.HasDiscriminator<string>("Discriminator").HasValue("VaultItem");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.PasteVaultItem", b =>
{
b.HasBaseType("Teknik.Areas.Vault.Models.VaultItem");
b.Property<int>("PasteId");
b.HasIndex("PasteId");
b.HasDiscriminator().HasValue("PasteVaultItem");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.UploadVaultItem", b =>
{
b.HasBaseType("Teknik.Areas.Vault.Models.VaultItem");
b.Property<int>("UploadId");
b.HasIndex("UploadId");
b.HasDiscriminator().HasValue("UploadVaultItem");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.Blog", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPost", b =>
{
b.HasOne("Teknik.Areas.Blog.Models.Blog", "Blog")
.WithMany("BlogPosts")
.HasForeignKey("BlogId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostComment", b =>
{
b.HasOne("Teknik.Areas.Blog.Models.BlogPost", "BlogPost")
.WithMany("Comments")
.HasForeignKey("BlogPostId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany()
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostTag", b =>
{
b.HasOne("Teknik.Areas.Blog.Models.BlogPost", "BlogPost")
.WithMany("Tags")
.HasForeignKey("BlogPostId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Paste.Models.Paste", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Pastes")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastComment", b =>
{
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
.WithMany("Comments")
.HasForeignKey("PodcastId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastFile", b =>
{
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
.WithMany("Files")
.HasForeignKey("PodcastId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastTag", b =>
{
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
.WithMany("Tags")
.HasForeignKey("PodcastId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Shortener.Models.ShortenedUrl", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("ShortenedUrls")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Upload.Models.Upload", b =>
{
b.HasOne("Teknik.Areas.Stats.Models.Takedown")
.WithMany("Attachments")
.HasForeignKey("Takedown_TakedownId");
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Uploads")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.InviteCode", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "ClaimedUser")
.WithOne("ClaimedInviteCode")
.HasForeignKey("Teknik.Areas.Users.Models.InviteCode", "ClaimedUserId");
b.HasOne("Teknik.Areas.Users.Models.User", "Owner")
.WithMany("OwnedInviteCodes")
.HasForeignKey("OwnerId");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.LoginInfo", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Logins")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Users.Models.User", b =>
{
b.OwnsOne("Teknik.Areas.Users.Models.BlogSettings", "BlogSettings", b1 =>
{
b1.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b1.Property<string>("Description")
.HasColumnName("Description");
b1.Property<string>("Title")
.HasColumnName("Title");
b1.HasKey("UserId");
b1.ToTable("Users");
b1.HasOne("Teknik.Areas.Users.Models.User")
.WithOne("BlogSettings")
.HasForeignKey("Teknik.Areas.Users.Models.BlogSettings", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
b.OwnsOne("Teknik.Areas.Users.Models.UploadSettings", "UploadSettings", b1 =>
{
b1.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b1.Property<bool>("Encrypt")
.HasColumnName("Encrypt");
b1.Property<int>("ExpireLength")
.HasColumnName("ExpireLength");
b1.Property<int>("ExpireUnit")
.HasColumnName("ExpireUnit");
b1.HasKey("UserId");
b1.ToTable("Users");
b1.HasOne("Teknik.Areas.Users.Models.User")
.WithOne("UploadSettings")
.HasForeignKey("Teknik.Areas.Users.Models.UploadSettings", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
b.OwnsOne("Teknik.Areas.Users.Models.UserSettings", "UserSettings", b1 =>
{
b1.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b1.Property<string>("About")
.HasColumnName("About");
b1.Property<string>("Quote")
.HasColumnName("Quote");
b1.Property<string>("Website")
.HasColumnName("Website");
b1.HasKey("UserId");
b1.ToTable("Users");
b1.HasOne("Teknik.Areas.Users.Models.User")
.WithOne("UserSettings")
.HasForeignKey("Teknik.Areas.Users.Models.UserSettings", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.Vault", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Vaults")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.VaultItem", b =>
{
b.HasOne("Teknik.Areas.Vault.Models.Vault", "Vault")
.WithMany("VaultItems")
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.PasteVaultItem", b =>
{
b.HasOne("Teknik.Areas.Paste.Models.Paste", "Paste")
.WithMany("PasteVaultItems")
.HasForeignKey("PasteId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.UploadVaultItem", b =>
{
b.HasOne("Teknik.Areas.Upload.Models.Upload", "Upload")
.WithMany("UploadVaultItems")
.HasForeignKey("UploadId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace Teknik.Data.Migrations
{
public partial class UploadExpirationSettings : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ExpireLength",
table: "Users",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "ExpireUnit",
table: "Users",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ExpireLength",
table: "Users");
migrationBuilder.DropColumn(
name: "ExpireUnit",
table: "Users");
}
}
}

View File

@ -0,0 +1,749 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Teknik.Data;
namespace Teknik.Data.Migrations
{
[DbContext(typeof(TeknikEntities))]
[Migration("20190117075302_ModifiedUploadSettings")]
partial class ModifiedUploadSettings
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.2.0-preview3-35497")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Teknik.Areas.Blog.Models.Blog", b =>
{
b.Property<int>("BlogId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("UserId");
b.HasKey("BlogId");
b.HasIndex("UserId");
b.ToTable("Blogs");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPost", b =>
{
b.Property<int>("BlogPostId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Article");
b.Property<int>("BlogId");
b.Property<DateTime>("DateEdited");
b.Property<DateTime>("DatePosted");
b.Property<DateTime>("DatePublished");
b.Property<bool>("Published");
b.Property<bool>("System");
b.Property<string>("Title");
b.HasKey("BlogPostId");
b.HasIndex("BlogId");
b.ToTable("BlogPosts");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostComment", b =>
{
b.Property<int>("BlogPostCommentId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Article");
b.Property<int>("BlogPostId");
b.Property<DateTime>("DateEdited");
b.Property<DateTime>("DatePosted");
b.Property<int?>("UserId");
b.HasKey("BlogPostCommentId");
b.HasIndex("BlogPostId");
b.HasIndex("UserId");
b.ToTable("BlogPostComments");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostTag", b =>
{
b.Property<int>("BlogPostTagId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("BlogPostId");
b.Property<string>("Description");
b.Property<string>("Name");
b.HasKey("BlogPostTagId");
b.HasIndex("BlogPostId");
b.ToTable("BlogPostTags");
});
modelBuilder.Entity("Teknik.Areas.Contact.Models.Contact", b =>
{
b.Property<int>("ContactId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateAdded");
b.Property<string>("Email");
b.Property<string>("Message");
b.Property<string>("Name");
b.Property<string>("Subject");
b.HasKey("ContactId");
b.ToTable("Contact");
});
modelBuilder.Entity("Teknik.Areas.Paste.Models.Paste", b =>
{
b.Property<int>("PasteId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("BlockSize");
b.Property<string>("Content");
b.Property<DateTime>("DatePosted");
b.Property<string>("DeleteKey")
.HasAnnotation("CaseSensitive", true);
b.Property<DateTime?>("ExpireDate");
b.Property<string>("FileName")
.HasAnnotation("CaseSensitive", true);
b.Property<string>("HashedPassword")
.HasAnnotation("CaseSensitive", true);
b.Property<bool>("Hide");
b.Property<string>("IV")
.HasAnnotation("CaseSensitive", true);
b.Property<string>("Key")
.HasAnnotation("CaseSensitive", true);
b.Property<int>("KeySize");
b.Property<int>("MaxViews");
b.Property<string>("Syntax");
b.Property<string>("Title");
b.Property<string>("Url")
.HasAnnotation("CaseSensitive", true);
b.Property<int?>("UserId");
b.Property<int>("Views");
b.HasKey("PasteId");
b.HasIndex("UserId");
b.ToTable("Pastes");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.Podcast", b =>
{
b.Property<int>("PodcastId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateEdited");
b.Property<DateTime>("DatePosted");
b.Property<DateTime>("DatePublished");
b.Property<string>("Description");
b.Property<int>("Episode");
b.Property<bool>("Published");
b.Property<string>("Title");
b.HasKey("PodcastId");
b.ToTable("Podcasts");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastComment", b =>
{
b.Property<int>("PodcastCommentId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Article");
b.Property<DateTime>("DateEdited");
b.Property<DateTime>("DatePosted");
b.Property<int>("PodcastId");
b.Property<int>("UserId");
b.HasKey("PodcastCommentId");
b.HasIndex("PodcastId");
b.HasIndex("UserId");
b.ToTable("PodcastComments");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastFile", b =>
{
b.Property<int>("PodcastFileId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<long>("ContentLength");
b.Property<string>("ContentType");
b.Property<string>("FileName");
b.Property<string>("Path");
b.Property<int>("PodcastId");
b.Property<int>("Size");
b.HasKey("PodcastFileId");
b.HasIndex("PodcastId");
b.ToTable("PodcastFiles");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastTag", b =>
{
b.Property<int>("PodcastTagId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Description");
b.Property<string>("Name");
b.Property<int>("PodcastId");
b.HasKey("PodcastTagId");
b.HasIndex("PodcastId");
b.ToTable("PodcastTags");
});
modelBuilder.Entity("Teknik.Areas.Shortener.Models.ShortenedUrl", b =>
{
b.Property<int>("ShortenedUrlId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateAdded");
b.Property<string>("OriginalUrl");
b.Property<string>("ShortUrl")
.HasAnnotation("CaseSensitive", true);
b.Property<int?>("UserId");
b.Property<int>("Views");
b.HasKey("ShortenedUrlId");
b.HasIndex("UserId");
b.ToTable("ShortenedUrls");
});
modelBuilder.Entity("Teknik.Areas.Stats.Models.Takedown", b =>
{
b.Property<int>("TakedownId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ActionTaken");
b.Property<DateTime>("DateActionTaken");
b.Property<DateTime>("DateRequested");
b.Property<string>("Reason");
b.Property<string>("Requester");
b.Property<string>("RequesterContact");
b.HasKey("TakedownId");
b.ToTable("Takedowns");
});
modelBuilder.Entity("Teknik.Areas.Stats.Models.Transaction", b =>
{
b.Property<int>("TransactionId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<decimal>("Amount")
.HasColumnType("decimal(19, 5)");
b.Property<int>("Currency");
b.Property<DateTime>("DateSent");
b.Property<string>("Reason");
b.HasKey("TransactionId");
b.ToTable("Transactions");
});
modelBuilder.Entity("Teknik.Areas.Upload.Models.Upload", b =>
{
b.Property<int>("UploadId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("BlockSize");
b.Property<long>("ContentLength");
b.Property<string>("ContentType");
b.Property<DateTime>("DateUploaded");
b.Property<string>("DeleteKey")
.HasAnnotation("CaseSensitive", true);
b.Property<int>("Downloads");
b.Property<DateTime?>("ExpireDate");
b.Property<string>("FileName")
.HasAnnotation("CaseSensitive", true);
b.Property<string>("IV")
.HasAnnotation("CaseSensitive", true);
b.Property<string>("Key")
.HasAnnotation("CaseSensitive", true);
b.Property<int>("KeySize");
b.Property<int>("MaxDownloads");
b.Property<int?>("Takedown_TakedownId");
b.Property<string>("Url")
.HasAnnotation("CaseSensitive", true);
b.Property<int?>("UserId");
b.HasKey("UploadId");
b.HasIndex("Takedown_TakedownId");
b.HasIndex("UserId");
b.ToTable("Uploads");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.InviteCode", b =>
{
b.Property<int>("InviteCodeId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<bool>("Active");
b.Property<int?>("ClaimedUserId");
b.Property<string>("Code")
.HasAnnotation("CaseSensitive", true);
b.Property<int?>("OwnerId");
b.HasKey("InviteCodeId");
b.HasIndex("ClaimedUserId")
.IsUnique()
.HasFilter("[ClaimedUserId] IS NOT NULL");
b.HasIndex("OwnerId");
b.ToTable("InviteCodes");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.LoginInfo", b =>
{
b.Property<int>("LoginInfoId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("LoginProvider");
b.Property<string>("ProviderDisplayName");
b.Property<string>("ProviderKey");
b.Property<int>("UserId");
b.HasKey("LoginInfoId");
b.HasIndex("UserId");
b.ToTable("UserLogins");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.User", b =>
{
b.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Username");
b.HasKey("UserId");
b.ToTable("Users");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.Vault", b =>
{
b.Property<int>("VaultId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateCreated");
b.Property<DateTime>("DateEdited");
b.Property<string>("Description");
b.Property<string>("Title");
b.Property<string>("Url");
b.Property<int?>("UserId");
b.Property<int>("Views");
b.HasKey("VaultId");
b.HasIndex("UserId");
b.ToTable("Vaults");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.VaultItem", b =>
{
b.Property<int>("VaultItemId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DateAdded");
b.Property<string>("Description");
b.Property<string>("Discriminator")
.IsRequired();
b.Property<string>("Title");
b.Property<int>("VaultId");
b.HasKey("VaultItemId");
b.HasIndex("VaultId");
b.ToTable("VaultItems");
b.HasDiscriminator<string>("Discriminator").HasValue("VaultItem");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.PasteVaultItem", b =>
{
b.HasBaseType("Teknik.Areas.Vault.Models.VaultItem");
b.Property<int>("PasteId");
b.HasIndex("PasteId");
b.HasDiscriminator().HasValue("PasteVaultItem");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.UploadVaultItem", b =>
{
b.HasBaseType("Teknik.Areas.Vault.Models.VaultItem");
b.Property<int>("UploadId");
b.HasIndex("UploadId");
b.HasDiscriminator().HasValue("UploadVaultItem");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.Blog", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPost", b =>
{
b.HasOne("Teknik.Areas.Blog.Models.Blog", "Blog")
.WithMany("BlogPosts")
.HasForeignKey("BlogId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostComment", b =>
{
b.HasOne("Teknik.Areas.Blog.Models.BlogPost", "BlogPost")
.WithMany("Comments")
.HasForeignKey("BlogPostId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany()
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Blog.Models.BlogPostTag", b =>
{
b.HasOne("Teknik.Areas.Blog.Models.BlogPost", "BlogPost")
.WithMany("Tags")
.HasForeignKey("BlogPostId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Paste.Models.Paste", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Pastes")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastComment", b =>
{
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
.WithMany("Comments")
.HasForeignKey("PodcastId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastFile", b =>
{
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
.WithMany("Files")
.HasForeignKey("PodcastId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Podcast.Models.PodcastTag", b =>
{
b.HasOne("Teknik.Areas.Podcast.Models.Podcast", "Podcast")
.WithMany("Tags")
.HasForeignKey("PodcastId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Shortener.Models.ShortenedUrl", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("ShortenedUrls")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Upload.Models.Upload", b =>
{
b.HasOne("Teknik.Areas.Stats.Models.Takedown")
.WithMany("Attachments")
.HasForeignKey("Takedown_TakedownId");
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Uploads")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.InviteCode", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "ClaimedUser")
.WithOne("ClaimedInviteCode")
.HasForeignKey("Teknik.Areas.Users.Models.InviteCode", "ClaimedUserId");
b.HasOne("Teknik.Areas.Users.Models.User", "Owner")
.WithMany("OwnedInviteCodes")
.HasForeignKey("OwnerId");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.LoginInfo", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Logins")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Users.Models.User", b =>
{
b.OwnsOne("Teknik.Areas.Users.Models.BlogSettings", "BlogSettings", b1 =>
{
b1.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b1.Property<string>("Description")
.HasColumnName("Description");
b1.Property<string>("Title")
.HasColumnName("Title");
b1.HasKey("UserId");
b1.ToTable("Users");
b1.HasOne("Teknik.Areas.Users.Models.User")
.WithOne("BlogSettings")
.HasForeignKey("Teknik.Areas.Users.Models.BlogSettings", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
b.OwnsOne("Teknik.Areas.Users.Models.UploadSettings", "UploadSettings", b1 =>
{
b1.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b1.Property<bool>("Encrypt")
.HasColumnName("Encrypt");
b1.Property<int>("ExpirationLength")
.HasColumnName("ExpirationLength");
b1.Property<int>("ExpirationUnit")
.HasColumnName("ExpirationUnit");
b1.HasKey("UserId");
b1.ToTable("Users");
b1.HasOne("Teknik.Areas.Users.Models.User")
.WithOne("UploadSettings")
.HasForeignKey("Teknik.Areas.Users.Models.UploadSettings", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
b.OwnsOne("Teknik.Areas.Users.Models.UserSettings", "UserSettings", b1 =>
{
b1.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b1.Property<string>("About")
.HasColumnName("About");
b1.Property<string>("Quote")
.HasColumnName("Quote");
b1.Property<string>("Website")
.HasColumnName("Website");
b1.HasKey("UserId");
b1.ToTable("Users");
b1.HasOne("Teknik.Areas.Users.Models.User")
.WithOne("UserSettings")
.HasForeignKey("Teknik.Areas.Users.Models.UserSettings", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.Vault", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Vaults")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.VaultItem", b =>
{
b.HasOne("Teknik.Areas.Vault.Models.Vault", "Vault")
.WithMany("VaultItems")
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.PasteVaultItem", b =>
{
b.HasOne("Teknik.Areas.Paste.Models.Paste", "Paste")
.WithMany("PasteVaultItems")
.HasForeignKey("PasteId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Vault.Models.UploadVaultItem", b =>
{
b.HasOne("Teknik.Areas.Upload.Models.Upload", "Upload")
.WithMany("UploadVaultItems")
.HasForeignKey("UploadId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,43 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace Teknik.Data.Migrations
{
public partial class ModifiedUploadSettings : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ExpireLength",
table: "Users");
migrationBuilder.RenameColumn(
name: "ExpireUnit",
table: "Users",
newName: "ExpirationLength");
migrationBuilder.AddColumn<int>(
name: "ExpirationUnit",
table: "Users",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ExpirationUnit",
table: "Users");
migrationBuilder.RenameColumn(
name: "ExpirationLength",
table: "Users",
newName: "ExpireUnit");
migrationBuilder.AddColumn<int>(
name: "ExpireLength",
table: "Users",
nullable: false,
defaultValue: 0);
}
}
}

View File

@ -669,6 +669,12 @@ namespace Teknik.Data.Migrations
b1.Property<bool>("Encrypt")
.HasColumnName("Encrypt");
b1.Property<int>("ExpirationLength")
.HasColumnName("ExpirationLength");
b1.Property<int>("ExpirationUnit")
.HasColumnName("ExpirationUnit");
b1.HasKey("UserId");
b1.ToTable("Users");

View File

@ -19,7 +19,20 @@ $(document).ready(function () {
$('#add-to-vault-menu').find('.add-to-vault').each(function () {
linkAddToVault($(this));
});
$('#uploadSettings').on('shown.bs.modal', function (e) {
// Initialize the widths
setExpireWidth($('#uploadSettings').find("#expireunit").val());
linkExpireSelect($('#uploadSettings').find("#expireunit"));
});
});
function linkExpireSelect(element) {
element.change(function () {
setExpireWidth($(this).val());
});
}
function linkUploadDelete(element, deleteUrl) {
element.click(function () {
@ -148,6 +161,19 @@ function linkAddToVault(element) {
});
}
function setExpireWidth(unit) {
if (unit === "Never") {
$('#length-div').addClass("hidden");
$('#unit-div').removeClass("col-sm-8");
$('#unit-div').addClass("col-sm-12");
}
else {
$('#length-div').removeClass("hidden");
$('#unit-div').removeClass("col-sm-12");
$('#unit-div').addClass("col-sm-8");
}
}
var dropZone = new Dropzone(document.body, {
url: uploadFileURL,
maxFilesize: maxUploadSize, // MB
@ -216,14 +242,22 @@ function processFile(fileBlob, fileName, contentType, contentSize, fileID, token
var fileExt = getFileExtension(fileName);
// Get session settings
var encrypt = $('#encrypt').is(':checked');
var encrypt = $('#uploadSettings').find('#encrypt').is(':checked');
var expireUnit = $('#uploadSettings').find("#expireunit").val();
var expireLength = $('#uploadSettings').find("#expirelength").val();
if (encrypt) {
var options = {
encrypt: encrypt,
expirationUnit: expireUnit,
expirationLength: expireLength
}
if (options.encrypt) {
// Encrypt the file and upload it
encryptFile(fileBlob, fileName, contentType, fileID, uploadFile, token);
encryptFile(fileBlob, fileName, contentType, fileID, uploadFile, options, token);
} else {
// pass it along
uploadFile(fileBlob, null, null, contentType, fileExt, fileID, encrypt, token);
uploadFile(fileBlob, null, null, contentType, fileExt, fileID, options, token);
}
}
else {
@ -233,12 +267,9 @@ function processFile(fileBlob, fileName, contentType, contentSize, fileID, token
}
// Function to encrypt a file, overide the file's data attribute with the encrypted value, and then call a callback function if supplied
function encryptFile(blob, fileName, contentType, ID, callback, token) {
function encryptFile(blob, fileName, contentType, ID, callback, options, token) {
var fileExt = getFileExtension(fileName);
// Get session settings
var encrypt = $('#encrypt').is(':checked');
// Start the file reader
var reader = new FileReader();
@ -246,8 +277,8 @@ function encryptFile(blob, fileName, contentType, ID, callback, token) {
reader.onload = (function (callback) {
return function (e) {
// Just send straight to server if they don't want to encrypt it
if (!encrypt) {
callback(e.target.result, null, null, contentType, fileExt, ID, encrypt, token);
if (!options.encrypt) {
callback(e.target.result, null, null, contentType, fileExt, ID, options, token);
}
else {
// Set variables for tracking
@ -276,7 +307,7 @@ function encryptFile(blob, fileName, contentType, ID, callback, token) {
case 'finish':
if (callback != null) {
// Finish
callback(e.data.buffer, keyStr, ivStr, contentType, fileExt, ID, encrypt, token);
callback(e.data.buffer, keyStr, ivStr, contentType, fileExt, ID, options, token);
}
break;
}
@ -333,7 +364,7 @@ function encryptFile(blob, fileName, contentType, ID, callback, token) {
reader.readAsArrayBuffer(blob);
}
function uploadFile(data, key, iv, filetype, fileExt, fileID, encrypt, token)
function uploadFile(data, key, iv, filetype, fileExt, fileID, options, token)
{
// Set variables for tracking
var startTime = (new Date()).getTime();
@ -347,13 +378,13 @@ function uploadFile(data, key, iv, filetype, fileExt, fileID, encrypt, token)
fd.append('iv', iv);
fd.append('keySize', keySize);
fd.append('blockSize', blockSize);
fd.append('options', JSON.stringify(options));
fd.append('file', blob);
fd.append('encrypt', !encrypt);
fd.append('__RequestVerificationToken', $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val());
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress.bind(null, fileID, startTime), false);
xhr.addEventListener("load", uploadComplete.bind(null, fileID, key, encrypt, token), false);
xhr.addEventListener("load", uploadComplete.bind(null, fileID, key, options, token), false);
xhr.addEventListener("error", uploadFailed.bind(null, fileID, token), false);
xhr.addEventListener("abort", uploadCanceled.bind(null, fileID, token), false);
@ -380,7 +411,7 @@ function uploadProgress(fileID, startTime, evt) {
}
}
function uploadComplete(fileID, key, encrypt, token, evt) {
function uploadComplete(fileID, key, options, token, evt) {
// Cancel out cancel token
token.callback = null;
@ -391,7 +422,7 @@ function uploadComplete(fileID, key, encrypt, token, evt) {
if (itemDiv) {
var name = obj.result.name;
var fullName = obj.result.url;
if (encrypt) {
if (options.encrypt) {
fullName = fullName + '#' + key;
}
var contentType = obj.result.contentType;
@ -411,6 +442,12 @@ function uploadComplete(fileID, key, encrypt, token, evt) {
itemDiv.find('#upload-contentType').html(contentType);
itemDiv.find('#upload-contentLength').html(contentLength);
var expirationMessage = options.expirationUnit;
if (options.expirationUnit !== "Never") {
expirationMessage = options.expirationLength + ' ' + options.expirationUnit;
}
itemDiv.find('#upload-expiration').html(expirationMessage);
// Setup the buttons
linkUploadDelete(itemDiv.find('#delete-link'), deleteUrl);
linkShortenUrl(itemDiv.find('#shortenUrl'), fileID, fullName);

View File

@ -1,16 +1,24 @@
$(document).ready(function () {
$("[name='update_upload_encrypt']").bootstrapSwitch();
$("[name='expireunit']").change(function () {
setExpireWidth($(this).val());
});
$("#update_submit").click(function () {
// Start Updating Animation
disableButton('#update_submit', 'Saving...');
upload_encrypt = $("#update_upload_encrypt").is(":checked");
upload_expireLength = $("#expirelength").val();
upload_expireUnit = $("#expireunit").val();
$.ajax({
type: "POST",
url: editURL,
data: AddAntiForgeryToken({
Encrypt: upload_encrypt
Encrypt: upload_encrypt,
ExpirationLength: upload_expireLength,
ExpirationUnit: upload_expireUnit
}),
success: function (response) {
if (response.result) {
@ -31,4 +39,20 @@ $(document).ready(function () {
});
return false;
});
// Initialize the widths
setExpireWidth($("[name='expireunit']").val());
});
function setExpireWidth(unit) {
if (unit === "Never") {
$('#length-div').addClass("hidden");
$('#unit-div').removeClass("col-sm-8");
$('#unit-div').addClass("col-sm-12");
}
else {
$('#length-div').removeClass("hidden");
$('#unit-div').removeClass("col-sm-12");
$('#unit-div').addClass("col-sm-8");
}
}

View File

@ -0,0 +1,40 @@
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Teknik.Utilities
{
public class FormDataJsonBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext));
// Fetch the value of the argument by name and set it to the model state
string fieldName = bindingContext.FieldName;
var valueProviderResult = bindingContext.ValueProvider.GetValue(fieldName);
if (valueProviderResult == ValueProviderResult.None) return Task.CompletedTask;
else bindingContext.ModelState.SetModelValue(fieldName, valueProviderResult);
// Do nothing if the value is null or empty
string value = valueProviderResult.FirstValue;
if (string.IsNullOrEmpty(value)) return Task.CompletedTask;
try
{
// Deserialize the provided value and set the binding result
object result = JsonConvert.DeserializeObject(value, bindingContext.ModelType);
bindingContext.Result = ModelBindingResult.Success(result);
}
catch (JsonException)
{
bindingContext.Result = ModelBindingResult.Failed();
}
return Task.CompletedTask;
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Teknik.Utilities
{
public enum ExpirationUnit
{
Never = 0,
Views = 1,
Minutes = 10,
Hours = 11,
Days = 12,
Months = 13,
Years = 14
}
}