Browse Source

Added Feature infrastructure and changed email accounts to start disabled for new accounts.

tags/3.0.0^2
Teknikode 6 months ago
parent
commit
8a6353f3da

+ 6
- 0
MailService/HMailService.cs View File

@@ -128,5 +128,11 @@ namespace Teknik.MailService
var domain = _App.Domains.ItemByName[_Domain];
return domain.Accounts.ItemByAddress[username];
}

public bool Enabled(string username)
{
var account = GetAccount(username);
return account.Active;
}
}
}

+ 2
- 0
MailService/IMailService.cs View File

@@ -8,6 +8,8 @@ namespace Teknik.MailService

DateTime LastActive(string username);

bool Enabled(string username);

void CreateAccount(string username, string password, int size);

void EditPassword(string username, string password);

+ 10
- 16
Teknik/Areas/About/Views/About/Index.cshtml View File

@@ -44,25 +44,13 @@
<td class="text-center"><i class="fa fa-times fa-2x text-danger"></i></td>
<td class="text-center"><i class="fa fa-times fa-2x text-danger"></i></td>
</tr>
<tr>
<td class="text-left">Email Storage</td>
<td class="text-center">5GB Storage</td>
<td class="text-center">1GB Storage</td>
<td class="text-center"><i class="fa fa-times fa-2x text-danger"></i></td>
</tr>
<tr>
<td class="text-left">Outbound Emails</td>
<td class="text-center">Unlimited</td>
<td class="text-center">100 per Day</td>
<td class="text-center"><i class="fa fa-times fa-2x text-danger"></i></td>
</tr>
<!-- Basic Features -->
<tr>
<td class="text-left">Email Account</td>
<td class="text-center"><i class="fa fa-check fa-2x text-success"></i></td>
<td class="text-center"><i class="fa fa-check fa-2x text-success"></i></td>
<td class="text-center"><i class="fa fa-times fa-2x text-danger"></i></td>
<td class="text-center"><i class="fa fa-times fa-2x text-danger"></i></td>
</tr>
<!-- Basic Features -->
<tr>
<td class="text-left">Git Repositories</td>
<td class="text-center">Unlimited Public &amp; Private Repos</td>
@@ -76,14 +64,14 @@
<td class="text-center"><i class="fa fa-times fa-2x text-danger"></i></td>
</tr>
<tr>
<td class="text-left">Vault Editing</td>
<td class="text-left">Vault and Paste Editing</td>
<td class="text-center"><i class="fa fa-check fa-2x text-success"></i></td>
<td class="text-center"><i class="fa fa-check fa-2x text-success"></i></td>
<td class="text-center"><i class="fa fa-times fa-2x text-danger"></i></td>
</tr>
<tr>
<td class="text-left">
View Content History:
View and Delete Previous Content:
<br />
<ul>
<li>Pastes</li>
@@ -121,6 +109,12 @@
<td class="text-center">@StringHelper.GetBytesReadable(Config.UploadConfig.MaxDownloadSize)</td>
<td class="text-center">@StringHelper.GetBytesReadable(Config.UploadConfig.MaxDownloadSize)</td>
</tr>
<tr>
<td class="text-left">Upload Expiration</td>
<td class="text-center">Never</td>
<td class="text-center">Never</td>
<td class="text-center">24 Hours</td>
</tr>
<tr>
<td class="text-left">Url Shortening</td>
<td class="text-center"><i class="fa fa-check fa-2x text-success"></i></td>

+ 19
- 2
Teknik/Areas/Contact/Views/Contact/Index.cshtml View File

@@ -1,5 +1,22 @@
@model Teknik.Areas.Contact.ViewModels.ContactViewModel

@using Teknik.Areas.Users.Utility

@{
string username = string.Empty;
string email = string.Empty;

if (User.Identity.IsAuthenticated)
{
username = User.Identity.Name;

if (UserHelper.UserEmailEnabled(Config, UserHelper.GetUserEmailAddress(Config, username)))
{
email = UserHelper.GetUserEmailAddress(Config, username);
}
}
}

<div class="container">
<div class="row">
<div class="col-sm-12 col-lg-12">
@@ -22,7 +39,7 @@
<label for="Name">
Name
</label>
<input type="text" class="form-control" id="Name" name="Name" placeholder="Enter name" required="required" value="@((User.Identity.IsAuthenticated) ? User.Identity.Name : string.Empty)" />
<input type="text" class="form-control" id="Name" name="Name" placeholder="Enter name" required="required" value="@username" />
</div>
<div class="form-group">
@Html.ValidationMessageFor(u => u.Email)
@@ -33,7 +50,7 @@
<span class="input-group-addon">
<span class="fa fa-envelope"></span>
</span>
<input type="email" class="form-control" id="Email" name="Email" placeholder="Enter email" required="required" value="@((User.Identity.IsAuthenticated) ? User.Identity.Name + "@" + Config.Host : string.Empty)" />
<input type="email" class="form-control" id="Email" name="Email" placeholder="Enter email" required="required" value="@email" />
</div>
</div>
<div class="form-group">

+ 18
- 0
Teknik/Areas/User/Models/Feature.cs View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Teknik.Areas.Users.Models
{
public class Feature
{
public string FeatureId { get; set; }

public string Name { get; set; }

public string Description { get; set; }

public bool Enabled { get; set; }
}
}

+ 0
- 22
Teknik/Areas/User/Models/LoginInfo.cs View File

@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Teknik.Areas.Users.Models
{
public class LoginInfo
{
public int LoginInfoId { get; set; }

public virtual string LoginProvider { get; set; }

public virtual string ProviderDisplayName { get; set; }

public virtual string ProviderKey { get; set; }

public int UserId { get; set; }

public virtual User User { get; set; }
}
}

+ 2
- 2
Teknik/Areas/User/Models/User.cs View File

@@ -15,7 +15,7 @@ namespace Teknik.Areas.Users.Models

public string Username { get; set; }

public virtual ICollection<LoginInfo> Logins { get; set; }
public virtual ICollection<UserFeature> Features { get; set; }

public virtual InviteCode ClaimedInviteCode { get; set; }

@@ -38,7 +38,7 @@ namespace Teknik.Areas.Users.Models
public User()
{
Username = string.Empty;
Logins = new List<LoginInfo>();
Features = new List<UserFeature>();
ClaimedInviteCode = null;
OwnedInviteCodes = new List<InviteCode>();
}

+ 20
- 0
Teknik/Areas/User/Models/UserFeature.cs View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Teknik.Areas.Users.Models
{
public class UserFeature
{
public int UserFeatureId { get; set; }

public string FeatureId { get; set; }

public virtual Feature Feature { get; set; }

public int UserId { get; set; }

public virtual User User { get; set; }
}
}

+ 28
- 0
Teknik/Areas/User/Utility/UserExtensions.cs View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Teknik.Areas.Users.Models;

namespace Teknik.Areas.Users.Utility
{
public static class UserExtensions
{
public static bool HasFeatures(this User user, params string[] features)
{
if (user.Features.Any())
{
return user.Features.Where(f => features.Contains(f.FeatureId)).FirstOrDefault() != null;
}
return false;
}
public static bool HasFeature(this User user, string feature)
{
if (user.Features.Any())
{
return user.Features.Where(f => f.FeatureId == feature).FirstOrDefault() != null;
}
return false;
}
}
}

+ 25
- 10
Teknik/Areas/User/Utility/UserHelper.cs View File

@@ -145,6 +145,9 @@ namespace Teknik.Areas.Users.Utility
// Create an Email Account
CreateUserEmail(config, GetUserEmailAddress(config, username), password);

// Disable the email account
DisableUserEmail(config, GetUserEmailAddress(config, username));

// Create a Git Account
CreateUserGit(config, username, password);

@@ -253,18 +256,12 @@ namespace Teknik.Areas.Users.Utility
switch (type)
{
case AccountType.Basic:
// Set the email size to 1GB
EditUserEmailMaxSize(config, email, config.EmailConfig.MaxSize);

// Set the email max/day to 100
EditUserEmailMaxEmailsPerDay(config, email, 100);
// Disable their email
DisableUserEmail(config, email);
break;
case AccountType.Premium:
// Set the email size to 5GB
EditUserEmailMaxSize(config, email, 5000);

// Set the email max/day to infinite (-1)
EditUserEmailMaxEmailsPerDay(config, email, -1);
// Enable their email account
EnableUserEmail(config, email);
break;
}
}
@@ -668,6 +665,24 @@ If you recieved this email and you did not reset your password, you can ignore t
return lastActive;
}

public static bool UserEmailEnabled(Config config, string email)
{
try
{
// If Email Server is enabled
if (config.EmailConfig.Enabled)
{
var svc = CreateMailService(config);
return svc.Enabled(email);
}
}
catch (Exception ex)
{
throw new Exception("Unable to disable email account.", ex);
}
return false;
}

public static void CreateUserEmail(Config config, string email, string password)
{
try

+ 767
- 0
Teknik/Data/Migrations/20190127224049_Features.Designer.cs View File

@@ -0,0 +1,767 @@
// <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("20190127224049_Features")]
partial class Features
{
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>("DateEdited");

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<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.Feature", b =>
{
b.Property<string>("FeatureId")
.ValueGeneratedOnAdd();

b.Property<string>("Description");

b.Property<bool>("Enabled");

b.Property<string>("Name");

b.HasKey("FeatureId");

b.ToTable("Features");
});

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.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.Users.Models.UserFeature", b =>
{
b.Property<int>("UserFeatureId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

b.Property<string>("FeatureId");

b.Property<int>("UserId");

b.HasKey("UserFeatureId");

b.HasIndex("FeatureId");

b.HasIndex("UserId");

b.ToTable("UserFeatures");
});

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.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.Users.Models.UserFeature", b =>
{
b.HasOne("Teknik.Areas.Users.Models.Feature", "Feature")
.WithMany()
.HasForeignKey("FeatureId");

b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Features")
.HasForeignKey("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
}
}
}

+ 100
- 0
Teknik/Data/Migrations/20190127224049_Features.cs View File

@@ -0,0 +1,100 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Teknik.Data.Migrations
{
public partial class Features : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserLogins");

migrationBuilder.CreateTable(
name: "Features",
columns: table => new
{
FeatureId = table.Column<string>(nullable: false),
Name = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true),
Enabled = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Features", x => x.FeatureId);
});

migrationBuilder.CreateTable(
name: "UserFeatures",
columns: table => new
{
UserFeatureId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
FeatureId = table.Column<string>(nullable: true),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserFeatures", x => x.UserFeatureId);
table.ForeignKey(
name: "FK_UserFeatures_Features_FeatureId",
column: x => x.FeatureId,
principalTable: "Features",
principalColumn: "FeatureId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_UserFeatures_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});

migrationBuilder.CreateIndex(
name: "IX_UserFeatures_FeatureId",
table: "UserFeatures",
column: "FeatureId");

migrationBuilder.CreateIndex(
name: "IX_UserFeatures_UserId",
table: "UserFeatures",
column: "UserId");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserFeatures");

migrationBuilder.DropTable(
name: "Features");

migrationBuilder.CreateTable(
name: "UserLogins",
columns: table => new
{
LoginInfoId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
LoginProvider = table.Column<string>(nullable: true),
ProviderDisplayName = table.Column<string>(nullable: true),
ProviderKey = table.Column<string>(nullable: true),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserLogins", x => x.LoginInfoId);
table.ForeignKey(
name: "FK_UserLogins_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});

migrationBuilder.CreateIndex(
name: "IX_UserLogins_UserId",
table: "UserLogins",
column: "UserId");
}
}
}

+ 44
- 26
Teknik/Data/Migrations/TeknikEntitiesModelSnapshot.cs View File

@@ -392,6 +392,22 @@ namespace Teknik.Data.Migrations
b.ToTable("Uploads");
});

modelBuilder.Entity("Teknik.Areas.Users.Models.Feature", b =>
{
b.Property<string>("FeatureId")
.ValueGeneratedOnAdd();

b.Property<string>("Description");

b.Property<bool>("Enabled");

b.Property<string>("Name");

b.HasKey("FeatureId");

b.ToTable("Features");
});

modelBuilder.Entity("Teknik.Areas.Users.Models.InviteCode", b =>
{
b.Property<int>("InviteCodeId")
@@ -418,38 +434,36 @@ namespace Teknik.Data.Migrations
b.ToTable("InviteCodes");
});

modelBuilder.Entity("Teknik.Areas.Users.Models.LoginInfo", b =>
modelBuilder.Entity("Teknik.Areas.Users.Models.User", b =>
{
b.Property<int>("LoginInfoId")
b.Property<int>("UserId")
.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.Property<string>("Username");

b.HasIndex("UserId");
b.HasKey("UserId");

b.ToTable("UserLogins");
b.ToTable("Users");
});

modelBuilder.Entity("Teknik.Areas.Users.Models.User", b =>
modelBuilder.Entity("Teknik.Areas.Users.Models.UserFeature", b =>
{
b.Property<int>("UserId")
b.Property<int>("UserFeatureId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

b.Property<string>("Username");
b.Property<string>("FeatureId");

b.HasKey("UserId");
b.Property<int>("UserId");

b.ToTable("Users");
b.HasKey("UserFeatureId");

b.HasIndex("FeatureId");

b.HasIndex("UserId");

b.ToTable("UserFeatures");
});

modelBuilder.Entity("Teknik.Areas.Vault.Models.Vault", b =>
@@ -628,14 +642,6 @@ namespace Teknik.Data.Migrations
.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 =>
@@ -711,6 +717,18 @@ namespace Teknik.Data.Migrations
});
});

modelBuilder.Entity("Teknik.Areas.Users.Models.UserFeature", b =>
{
b.HasOne("Teknik.Areas.Users.Models.Feature", "Feature")
.WithMany()
.HasForeignKey("FeatureId");

b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany("Features")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});

modelBuilder.Entity("Teknik.Areas.Vault.Models.Vault", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")

+ 11
- 3
Teknik/Data/TeknikEntities.cs View File

@@ -19,12 +19,14 @@ namespace Teknik.Data
{
// Users
public DbSet<User> Users { get; set; }
public DbSet<LoginInfo> UserLogins { get; set; }
public DbSet<InviteCode> InviteCodes { get; set; }
public DbSet<UserFeature> UserFeatures { get; set; }
// User Settings
public DbSet<UserSettings> UserSettings { get; set; }
public DbSet<BlogSettings> BlogSettings { get; set; }
public DbSet<UploadSettings> UploadSettings { get; set; }
// Features
public DbSet<Feature> Features { get; set; }
// Blogs
public DbSet<Blog> Blogs { get; set; }
public DbSet<BlogPost> BlogPosts { get; set; }
@@ -70,13 +72,13 @@ namespace Teknik.Data
modelBuilder.Entity<User>().OwnsOne(u => u.UserSettings);
modelBuilder.Entity<User>().OwnsOne(u => u.BlogSettings);
modelBuilder.Entity<User>().OwnsOne(u => u.UploadSettings);
modelBuilder.Entity<User>().HasMany(u => u.Features).WithOne(u => u.User);
modelBuilder.Entity<User>().HasMany(u => u.Uploads).WithOne(u => u.User);
modelBuilder.Entity<User>().HasMany(u => u.Pastes).WithOne(u => u.User);
modelBuilder.Entity<User>().HasMany(u => u.ShortenedUrls).WithOne(u => u.User);
modelBuilder.Entity<User>().HasMany(u => u.Vaults).WithOne(u => u.User);
modelBuilder.Entity<User>().HasMany(u => u.OwnedInviteCodes).WithOne(i => i.Owner);
modelBuilder.Entity<User>().HasOne(u => u.ClaimedInviteCode).WithOne(i => i.ClaimedUser);
modelBuilder.Entity<User>().HasMany(u => u.Logins).WithOne(r => r.User);
modelBuilder.Entity<User>().HasOne(u => u.ClaimedInviteCode).WithOne(t => t.ClaimedUser); // Legacy???
modelBuilder.Entity<User>().HasMany(u => u.OwnedInviteCodes).WithOne(t => t.Owner); // Legacy???

@@ -84,6 +86,10 @@ namespace Teknik.Data
//modelBuilder.Entity<InviteCode>().HasOne(t => t.ClaimedUser).WithOne(u => u.ClaimedInviteCode).HasPrincipalKey("ClaimedUserId").HasForeignKey("ClaimedUser_UserId"); // Legacy???
//modelBuilder.Entity<InviteCode>().HasOne(t => t.Owner).WithMany(u => u.OwnedInviteCodes).HasPrincipalKey("ClaimedUserId").HasForeignKey("Owner_UserId"); // Legacy???

// Features
modelBuilder.Entity<UserFeature>().HasOne(f => f.Feature);
modelBuilder.Entity<UserFeature>().HasOne(f => f.User);

// Blogs
modelBuilder.Entity<BlogPost>().HasMany(p => p.Comments).WithOne(c => c.BlogPost);

@@ -107,12 +113,14 @@ namespace Teknik.Data

// Users
modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<LoginInfo>().ToTable("UserLogins");
modelBuilder.Entity<InviteCode>().ToTable("InviteCodes");
modelBuilder.Entity<UserFeature>().ToTable("UserFeatures");
// User Settings
modelBuilder.Entity<UserSettings>().ToTable("Users");
modelBuilder.Entity<BlogSettings>().ToTable("Users");
modelBuilder.Entity<UploadSettings>().ToTable("Users");
// Features
modelBuilder.Entity<Feature>().ToTable("Features");
// Blogs
modelBuilder.Entity<Blog>().ToTable("Blogs");
modelBuilder.Entity<BlogPost>().ToTable("BlogPosts");

Loading…
Cancel
Save