mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
Modified pastes to save content to encrypted files instead of saving to the DB.
This commit is contained in:
parent
2799aac959
commit
0f7c912390
@ -1,19 +1,32 @@
|
||||
namespace Teknik.Configuration
|
||||
using System.IO;
|
||||
|
||||
namespace Teknik.Configuration
|
||||
{
|
||||
public class PasteConfig
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public int UrlLength { get; set; }
|
||||
public int DeleteKeyLength { get; set; }
|
||||
public string SyntaxVisualStyle { get; set; }
|
||||
// Location of the upload directory
|
||||
public string PasteDirectory { get; set; }
|
||||
// File Extension for saved files
|
||||
public string FileExtension { get; set; }
|
||||
public int KeySize { get; set; }
|
||||
public int BlockSize { get; set; }
|
||||
public string SyntaxVisualStyle { get; set; }
|
||||
// The size of the chunk that the file will be encrypted/decrypted in (bytes)
|
||||
public int ChunkSize { get; set; }
|
||||
|
||||
public PasteConfig()
|
||||
{
|
||||
Enabled = true;
|
||||
UrlLength = 5;
|
||||
DeleteKeyLength = 24;
|
||||
KeySize = 256;
|
||||
BlockSize = 128;
|
||||
ChunkSize = 1040;
|
||||
PasteDirectory = Directory.GetCurrentDirectory();
|
||||
FileExtension = "enc";
|
||||
SyntaxVisualStyle = "vs";
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Teknik.Logging;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Teknik.Areas.Paste.Controllers
|
||||
{
|
||||
@ -37,7 +39,7 @@ namespace Teknik.Areas.Paste.Controllers
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
public IActionResult ViewPaste(string type, string url, string password)
|
||||
public async Task<IActionResult> ViewPaste(string type, string url, string password)
|
||||
{
|
||||
Models.Paste paste = _dbContext.Pastes.Where(p => p.Url == url).FirstOrDefault();
|
||||
if (paste != null)
|
||||
@ -59,13 +61,10 @@ namespace Teknik.Areas.Paste.Controllers
|
||||
|
||||
PasteViewModel model = new PasteViewModel();
|
||||
model.Url = url;
|
||||
model.Content = paste.Content;
|
||||
model.Title = paste.Title;
|
||||
model.Syntax = paste.Syntax;
|
||||
model.DatePosted = paste.DatePosted;
|
||||
|
||||
byte[] data = Encoding.UTF8.GetBytes(paste.Content);
|
||||
|
||||
if (User.Identity.IsAuthenticated && type.ToLower() == "full")
|
||||
{
|
||||
Users.Models.User user = UserHelper.GetUser(_dbContext, User.Identity.Name);
|
||||
@ -75,23 +74,17 @@ namespace Teknik.Areas.Paste.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
byte[] ivBytes = Encoding.Unicode.GetBytes(paste.IV);
|
||||
byte[] keyBytes = AesCounterManaged.CreateKey(paste.Key, ivBytes, paste.KeySize);
|
||||
|
||||
// The paste has a password set
|
||||
if (!string.IsNullOrEmpty(paste.HashedPassword))
|
||||
{
|
||||
string hash = string.Empty;
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
byte[] passBytes = SHA384.Hash(paste.Key, password);
|
||||
hash = passBytes.ToHex();
|
||||
// We need to convert old pastes to the new password scheme
|
||||
//if (paste.Transfers.ToList().Exists(t => t.Type == TransferTypes.ASCIIPassword))
|
||||
//{
|
||||
// hash = Encoding.ASCII.GetString(passBytes);
|
||||
// // Remove the transfer types
|
||||
// paste.Transfers.Clear();
|
||||
// _dbContext.Entry(paste).State = EntityState.Modified;
|
||||
// _dbContext.SaveChanges();
|
||||
//}
|
||||
hash = PasteHelper.HashPassword(paste.Key, password);
|
||||
keyBytes = AesCounterManaged.CreateKey(password, ivBytes, paste.KeySize);
|
||||
}
|
||||
if (string.IsNullOrEmpty(password) || hash != paste.HashedPassword)
|
||||
{
|
||||
@ -108,13 +101,16 @@ namespace Teknik.Areas.Paste.Controllers
|
||||
// Redirect them to the password request page
|
||||
return View("~/Areas/Paste/Views/Paste/PasswordNeeded.cshtml", passModel);
|
||||
}
|
||||
}
|
||||
|
||||
data = Convert.FromBase64String(paste.Content);
|
||||
// Now we decrypt the content
|
||||
byte[] ivBytes = Encoding.Unicode.GetBytes(paste.IV);
|
||||
byte[] keyBytes = AesCounterManaged.CreateKey(password, ivBytes, paste.KeySize);
|
||||
data = AesCounterManaged.Decrypt(data, keyBytes, ivBytes);
|
||||
model.Content = Encoding.Unicode.GetString(data);
|
||||
// Read in the file
|
||||
string subDir = paste.FileName[0].ToString();
|
||||
string filePath = Path.Combine(_config.PasteConfig.PasteDirectory, subDir, paste.FileName);
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (AesCounterStream cs = new AesCounterStream(fs, false, keyBytes, ivBytes))
|
||||
using (StreamReader sr = new StreamReader(cs, Encoding.Unicode))
|
||||
{
|
||||
model.Content = await sr.ReadToEndAsync();
|
||||
}
|
||||
|
||||
switch (type.ToLower())
|
||||
@ -135,7 +131,8 @@ namespace Teknik.Areas.Paste.Controllers
|
||||
|
||||
Response.Headers.Add("Content-Disposition", cd.ToString());
|
||||
|
||||
return File(data, "application/octet-stream");
|
||||
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
return new BufferedFileStreamResult("application/octet-stream", async (response) => await ResponseHelper.StreamToOutput(response, true, new AesCounterStream(fs, false, keyBytes, ivBytes), (int)fs.Length, _config.PasteConfig.ChunkSize), false);
|
||||
default:
|
||||
return View("~/Areas/Paste/Views/Paste/Full.cshtml", model);
|
||||
}
|
||||
|
@ -24,6 +24,9 @@ namespace Teknik.Areas.Paste.Models
|
||||
[CaseSensitive]
|
||||
public string Url { get; set; }
|
||||
|
||||
[CaseSensitive]
|
||||
public string FileName { get; set; }
|
||||
|
||||
public string Content { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
@ -45,6 +48,9 @@ namespace Teknik.Areas.Paste.Models
|
||||
|
||||
public int BlockSize { get; set; }
|
||||
|
||||
[CaseSensitive]
|
||||
public string DeleteKey { get; set; }
|
||||
|
||||
public bool Hide { get; set; }
|
||||
|
||||
public int MaxViews { get; set; }
|
||||
|
@ -8,6 +8,7 @@ using Teknik.Utilities;
|
||||
using Teknik.Models;
|
||||
using Teknik.Utilities.Cryptography;
|
||||
using Teknik.Data;
|
||||
using System.IO;
|
||||
|
||||
namespace Teknik.Areas.Paste
|
||||
{
|
||||
@ -55,30 +56,49 @@ namespace Teknik.Areas.Paste
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the hashed password if one is provided and encrypt stuff
|
||||
if (!Directory.Exists(config.PasteConfig.PasteDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(config.PasteConfig.PasteDirectory);
|
||||
}
|
||||
|
||||
// Generate a unique file name that does not currently exist
|
||||
string filePath = FileHelper.GenerateRandomFileName(config.PasteConfig.PasteDirectory, config.PasteConfig.FileExtension, 10);
|
||||
string fileName = Path.GetFileName(filePath);
|
||||
|
||||
string key = GenerateKey(config.PasteConfig.KeySize);
|
||||
string iv = GenerateIV(config.PasteConfig.BlockSize);
|
||||
|
||||
byte[] ivBytes = Encoding.Unicode.GetBytes(iv);
|
||||
byte[] keyBytes = AesCounterManaged.CreateKey(key, ivBytes, config.PasteConfig.KeySize);
|
||||
|
||||
// Set the hashed password if one is provided and modify the key
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
string key = StringHelper.RandomString(config.PasteConfig.KeySize / 8);
|
||||
string iv = StringHelper.RandomString(config.PasteConfig.BlockSize / 16);
|
||||
paste.HashedPassword = SHA384.Hash(key, password).ToHex();
|
||||
paste.HashedPassword = HashPassword(key, password);
|
||||
keyBytes = AesCounterManaged.CreateKey(password, ivBytes, config.PasteConfig.KeySize);
|
||||
}
|
||||
|
||||
// Encrypt Content
|
||||
byte[] data = Encoding.Unicode.GetBytes(content);
|
||||
byte[] ivBytes = Encoding.Unicode.GetBytes(iv);
|
||||
byte[] keyBytes = AesCounterManaged.CreateKey(password, ivBytes, config.PasteConfig.KeySize);
|
||||
byte[] encData = AesCounterManaged.Encrypt(data, keyBytes, ivBytes);
|
||||
content = Convert.ToBase64String(encData);
|
||||
using (MemoryStream ms = new MemoryStream(data))
|
||||
{
|
||||
AesCounterManaged.EncryptToFile(filePath, ms, config.PasteConfig.ChunkSize, keyBytes, ivBytes);
|
||||
}
|
||||
|
||||
// Generate a deletion key
|
||||
string delKey = StringHelper.RandomString(config.PasteConfig.DeleteKeyLength);
|
||||
|
||||
paste.Key = key;
|
||||
paste.KeySize = config.PasteConfig.KeySize;
|
||||
paste.IV = iv;
|
||||
paste.BlockSize = config.PasteConfig.BlockSize;
|
||||
}
|
||||
|
||||
paste.Content = content;
|
||||
paste.FileName = fileName;
|
||||
//paste.Content = content;
|
||||
paste.Title = title;
|
||||
paste.Syntax = syntax;
|
||||
paste.Hide = hide;
|
||||
paste.DeleteKey = delKey;
|
||||
|
||||
return paste;
|
||||
}
|
||||
@ -92,5 +112,20 @@ namespace Teknik.Areas.Paste
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string GenerateKey(int keySize)
|
||||
{
|
||||
return StringHelper.RandomString(keySize / 8);
|
||||
}
|
||||
|
||||
public static string GenerateIV(int ivSize)
|
||||
{
|
||||
return StringHelper.RandomString(ivSize / 16);
|
||||
}
|
||||
|
||||
public static string HashPassword(string key, string password)
|
||||
{
|
||||
return SHA384.Hash(key, password).ToHex();
|
||||
}
|
||||
}
|
||||
}
|
@ -64,11 +64,14 @@ namespace Teknik.Areas.Upload.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 (file.Length <= maxUploadSize)
|
||||
{
|
||||
|
@ -42,6 +42,10 @@ namespace Teknik.Areas.Upload.Models
|
||||
[CaseSensitive]
|
||||
public string DeleteKey { get; set; }
|
||||
|
||||
public DateTime? ExpireDate { get; set; }
|
||||
|
||||
public int MaxDownloads { get; set; }
|
||||
|
||||
public int Downloads { get; set; }
|
||||
}
|
||||
}
|
743
Teknik/Data/Migrations/20181121074110_PasteFiles.Designer.cs
generated
Normal file
743
Teknik/Data/Migrations/20181121074110_PasteFiles.Designer.cs
generated
Normal file
@ -0,0 +1,743 @@
|
||||
// <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("20181121074110_PasteFiles")]
|
||||
partial class PasteFiles
|
||||
{
|
||||
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.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
|
||||
}
|
||||
}
|
||||
}
|
51
Teknik/Data/Migrations/20181121074110_PasteFiles.cs
Normal file
51
Teknik/Data/Migrations/20181121074110_PasteFiles.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace Teknik.Data.Migrations
|
||||
{
|
||||
public partial class PasteFiles : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "ExpireDate",
|
||||
table: "Uploads",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "MaxDownloads",
|
||||
table: "Uploads",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DeleteKey",
|
||||
table: "Pastes",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "FileName",
|
||||
table: "Pastes",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ExpireDate",
|
||||
table: "Uploads");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MaxDownloads",
|
||||
table: "Uploads");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DeleteKey",
|
||||
table: "Pastes");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FileName",
|
||||
table: "Pastes");
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace Teknik.Data.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.2.0-preview2-35157")
|
||||
.HasAnnotation("ProductVersion", "2.2.0-preview3-35497")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
@ -140,8 +140,14 @@ namespace Teknik.Data.Migrations
|
||||
|
||||
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);
|
||||
|
||||
@ -355,6 +361,8 @@ namespace Teknik.Data.Migrations
|
||||
|
||||
b.Property<int>("Downloads");
|
||||
|
||||
b.Property<DateTime?>("ExpireDate");
|
||||
|
||||
b.Property<string>("FileName")
|
||||
.HasAnnotation("CaseSensitive", true);
|
||||
|
||||
@ -366,6 +374,8 @@ namespace Teknik.Data.Migrations
|
||||
|
||||
b.Property<int>("KeySize");
|
||||
|
||||
b.Property<int>("MaxDownloads");
|
||||
|
||||
b.Property<int?>("Takedown_TakedownId");
|
||||
|
||||
b.Property<string>("Url")
|
||||
|
Loading…
Reference in New Issue
Block a user