Browse Source

Moved security specific settings to it's own model.

tags/2.0.3
Teknikode 4 years ago
parent
commit
b9fb94e685

+ 20
- 18
Teknik/Areas/User/Controllers/UserController.cs View File

@@ -60,6 +60,7 @@ namespace Teknik.Areas.Users.Controllers
model.LastSeen = UserHelper.GetLastAccountActivity(db, Config, user);

model.UserSettings = user.UserSettings;
model.SecuritySettings = user.SecuritySettings;
model.BlogSettings = user.BlogSettings;
model.UploadSettings = user.UploadSettings;

@@ -103,10 +104,9 @@ namespace Teknik.Areas.Users.Controllers

model.UserID = user.UserId;
model.Username = user.Username;
model.RecoveryEmail = user.RecoveryEmail;
model.RecoveryVerified = user.RecoveryVerified;

model.UserSettings = user.UserSettings;
model.SecuritySettings = user.SecuritySettings;
model.BlogSettings = user.BlogSettings;
model.UploadSettings = user.UploadSettings;

@@ -129,9 +129,9 @@ namespace Teknik.Areas.Users.Controllers
User user = UserHelper.GetUser(db, username);
if (user != null)
{
if (!string.IsNullOrEmpty(user.UserSettings.PGPSignature))
if (!string.IsNullOrEmpty(user.SecuritySettings.PGPSignature))
{
return Content(user.UserSettings.PGPSignature, "text/plain");
return Content(user.SecuritySettings.PGPSignature, "text/plain");
}
}
return Redirect(Url.SubRouteUrl("error", "Error.Http404"));
@@ -241,14 +241,16 @@ namespace Teknik.Areas.Users.Controllers
User newUser = db.Users.Create();
newUser.JoinDate = DateTime.Now;
newUser.Username = model.Username;
if (!string.IsNullOrEmpty(model.RecoveryEmail))
newUser.RecoveryEmail = model.RecoveryEmail;
newUser.UserSettings = new UserSettings();
if (!string.IsNullOrEmpty(model.PublicKey))
newUser.UserSettings.PGPSignature = model.PublicKey;
newUser.SecuritySettings = new SecuritySettings();
newUser.BlogSettings = new BlogSettings();
newUser.UploadSettings = new UploadSettings();

if (!string.IsNullOrEmpty(model.PublicKey))
newUser.SecuritySettings.PGPSignature = model.PublicKey;
if (!string.IsNullOrEmpty(model.RecoveryEmail))
newUser.SecuritySettings.RecoveryEmail = model.RecoveryEmail;

UserHelper.AddAccount(db, Config, newUser, model.Password);
// If they have a recovery email, let's send a verification
@@ -304,14 +306,14 @@ namespace Teknik.Areas.Users.Controllers
{
return Json(new { error = "Invalid PGP Public Key" });
}
user.UserSettings.PGPSignature = pgpPublicKey;
user.SecuritySettings.PGPSignature = pgpPublicKey;

bool newRecovery = false;
if (recoveryEmail != user.RecoveryEmail)
if (recoveryEmail != user.SecuritySettings.RecoveryEmail)
{
newRecovery = true;
user.RecoveryEmail = recoveryEmail;
user.RecoveryVerified = false;
user.SecuritySettings.RecoveryEmail = recoveryEmail;
user.SecuritySettings.RecoveryVerified = false;
}

user.UserSettings.Website = website;
@@ -331,7 +333,7 @@ namespace Teknik.Areas.Users.Controllers
string verifyCode = UserHelper.CreateRecoveryEmailVerification(db, Config, user);
string resetUrl = Url.SubRouteUrl("user", "User.ResetPassword", new { Username = user.Username });
string verifyUrl = Url.SubRouteUrl("user", "User.VerifyRecoveryEmail", new { Code = verifyCode });
UserHelper.SendRecoveryEmailVerification(Config, user.Username, user.RecoveryEmail, resetUrl, verifyUrl);
UserHelper.SendRecoveryEmailVerification(Config, user.Username, user.SecuritySettings.RecoveryEmail, resetUrl, verifyUrl);
}
return Json(new { result = true });
}
@@ -394,14 +396,14 @@ namespace Teknik.Areas.Users.Controllers
if (user != null)
{
// If they have a recovery email, let's send a verification
if (!string.IsNullOrEmpty(user.RecoveryEmail))
if (!string.IsNullOrEmpty(user.SecuritySettings.RecoveryEmail))
{
if (!user.RecoveryVerified)
if (!user.SecuritySettings.RecoveryVerified)
{
string verifyCode = UserHelper.CreateRecoveryEmailVerification(db, Config, user);
string resetUrl = Url.SubRouteUrl("user", "User.ResetPassword", new { Username = user.Username });
string verifyUrl = Url.SubRouteUrl("user", "User.VerifyRecoveryEmail", new { Code = verifyCode });
UserHelper.SendRecoveryEmailVerification(Config, user.Username, user.RecoveryEmail, resetUrl, verifyUrl);
UserHelper.SendRecoveryEmailVerification(Config, user.Username, user.SecuritySettings.RecoveryEmail, resetUrl, verifyUrl);
return Json(new { result = true });
}
return Json(new { error = "The recovery email is already verified" });
@@ -438,11 +440,11 @@ namespace Teknik.Areas.Users.Controllers
if (user != null)
{
// If they have a recovery email, let's send a verification
if (!string.IsNullOrEmpty(user.RecoveryEmail) && user.RecoveryVerified)
if (!string.IsNullOrEmpty(user.SecuritySettings.RecoveryEmail) && user.SecuritySettings.RecoveryVerified)
{
string verifyCode = UserHelper.CreateResetPasswordVerification(db, Config, user);
string resetUrl = Url.SubRouteUrl("user", "User.VerifyResetPassword", new { Username = user.Username, Code = verifyCode });
UserHelper.SendResetPasswordVerification(Config, user.Username, user.RecoveryEmail, resetUrl);
UserHelper.SendResetPasswordVerification(Config, user.Username, user.SecuritySettings.RecoveryEmail, resetUrl);
return Json(new { result = true });
}
return Json(new { error = "The username doesn't have a recovery email specified" });

+ 6
- 4
Teknik/Areas/User/Models/BlogSettings.cs View File

@@ -13,16 +13,18 @@ namespace Teknik.Areas.Users.Models
[Key]
public int UserId { get; set; }

public string Title { get; set; }

public string Description { get; set; }

public virtual User User { get; set; }

public virtual SecuritySettings SecuritySettings { get; set; }

public virtual UserSettings UserSettings { get; set; }

public virtual UploadSettings UploadSettings { get; set; }

public string Title { get; set; }

public string Description { get; set; }

public BlogSettings()
{
Title = string.Empty;

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

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Attributes;

namespace Teknik.Areas.Users.Models
{
@@ -13,6 +14,7 @@ namespace Teknik.Areas.Users.Models

public virtual User User { get; set; }

[CaseSensitive]
public string Code { get; set; }

public DateTime DateCreated { get; set; }

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

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Attributes;

namespace Teknik.Areas.Users.Models
{
@@ -13,6 +14,7 @@ namespace Teknik.Areas.Users.Models

public virtual User User { get; set; }

[CaseSensitive]
public string Code { get; set; }

public DateTime DateCreated { get; set; }

+ 43
- 0
Teknik/Areas/User/Models/SecuritySettings.cs View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using Teknik.Attributes;

namespace Teknik.Areas.Users.Models
{
public class SecuritySettings
{
[Key]
public int UserId { get; set; }

public virtual User User { get; set; }

public virtual UserSettings UserSettings { get; set; }

public virtual BlogSettings BlogSettings { get; set; }

public virtual UploadSettings UploadSettings { get; set; }

public string RecoveryEmail { get; set; }

public bool RecoveryVerified { get; set; }

public bool TwoFactorEnabled { get; set; }

[CaseSensitive]
public string TwoFactorKey { get; set; }

public string PGPSignature { get; set; }

public SecuritySettings()
{
RecoveryEmail = string.Empty;
RecoveryVerified = false;
TwoFactorEnabled = false;
TwoFactorKey = string.Empty;
PGPSignature = string.Empty;
}
}
}

+ 6
- 4
Teknik/Areas/User/Models/UploadSettings.cs View File

@@ -13,16 +13,18 @@ namespace Teknik.Areas.Users.Models
[Key]
public int UserId { get; set; }

public bool SaveKey { get; set; }

public bool ServerSideEncrypt { get; set; }

public virtual User User { get; set; }

public virtual SecuritySettings SecuritySettings { get; set; }

public virtual BlogSettings BlogSettings { get; set; }

public virtual UserSettings UserSettings { get; set; }

public bool SaveKey { get; set; }

public bool ServerSideEncrypt { get; set; }

public UploadSettings()
{
SaveKey = true;

+ 3
- 10
Teknik/Areas/User/Models/User.cs View File

@@ -17,10 +17,6 @@ namespace Teknik.Areas.Users.Models
[CaseSensitive]
public string HashedPassword { get; set; }

public string RecoveryEmail { get; set; }

public bool RecoveryVerified { get; set; }

public virtual ICollection<TransferType> Transfers { get; set; }

public DateTime JoinDate { get; set; }
@@ -30,7 +26,9 @@ namespace Teknik.Areas.Users.Models
public virtual ICollection<Group> Groups { get; set; }
public virtual UserSettings UserSettings { get; set; }

public virtual SecuritySettings SecuritySettings { get; set; }

public virtual BlogSettings BlogSettings { get; set; }
public virtual UploadSettings UploadSettings { get; set; }
@@ -43,15 +41,10 @@ namespace Teknik.Areas.Users.Models
{
Username = string.Empty;
HashedPassword = string.Empty;
RecoveryEmail = string.Empty;
RecoveryVerified = false;
Transfers = new List<TransferType>();
JoinDate = DateTime.Now;
LastSeen = DateTime.Now;
Groups = new List<Group>();
//UserSettings = new UserSettings();
//BlogSettings = new BlogSettings();
//UploadSettings = new UploadSettings();
}
}
}

+ 7
- 8
Teknik/Areas/User/Models/UserSettings.cs View File

@@ -13,26 +13,25 @@ namespace Teknik.Areas.Users.Models
[Key]
public int UserId { get; set; }

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

public string Website { get; set; }
public virtual SecuritySettings SecuritySettings { get; set; }

public string Quote { get; set; }
public virtual BlogSettings BlogSettings { get; set; }

public string PGPSignature { get; set; }
public virtual UploadSettings UploadSettings { get; set; }

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

public virtual BlogSettings BlogSettings { get; set; }
public string Website { get; set; }

public virtual UploadSettings UploadSettings { get; set; }
public string Quote { get; set; }

public UserSettings()
{
About = string.Empty;
Website = string.Empty;
Quote = string.Empty;
PGPSignature = string.Empty;
}
}
}

+ 2
- 1
Teknik/Areas/User/Utility/UserHelper.cs View File

@@ -204,6 +204,7 @@ namespace Teknik.Areas.Users.Utility
if (user != null)
{
user.UserSettings = db.UserSettings.Find(user.UserId);
user.SecuritySettings = db.SecuritySettings.Find(user.UserId);
user.BlogSettings = db.BlogSettings.Find(user.UserId);
user.UploadSettings = db.UploadSettings.Find(user.UserId);
}
@@ -495,7 +496,7 @@ Thank you and enjoy!
}
}
// Update the user
user.RecoveryVerified = true;
user.SecuritySettings.RecoveryVerified = true;
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();


+ 2
- 0
Teknik/Areas/User/ViewModels/ProfileViewModel.cs View File

@@ -27,6 +27,8 @@ namespace Teknik.Areas.Users.ViewModels

public UserSettings UserSettings { get; set; }

public SecuritySettings SecuritySettings { get; set; }

public BlogSettings BlogSettings { get; set; }

public UploadSettings UploadSettings { get; set; }

+ 2
- 4
Teknik/Areas/User/ViewModels/SettingsViewModel.cs View File

@@ -13,12 +13,10 @@ namespace Teknik.Areas.Users.ViewModels

public string Username { get; set; }

public string RecoveryEmail { get; set; }

public bool RecoveryVerified { get; set; }

public UserSettings UserSettings { get; set; }

public SecuritySettings SecuritySettings { get; set; }

public BlogSettings BlogSettings { get; set; }

public UploadSettings UploadSettings { get; set; }

+ 4
- 4
Teknik/Areas/User/Views/User/Index.cshtml View File

@@ -14,10 +14,10 @@
string pgpFingerprint = pgpFingerprint = string.Empty;
string pgpFingerprint64 = string.Empty;

if (!string.IsNullOrEmpty(Model.UserSettings.PGPSignature))
if (!string.IsNullOrEmpty(Model.SecuritySettings.PGPSignature))
{
pgpFingerprint = PGP.GetFingerprint(Model.UserSettings.PGPSignature);
pgpFingerprint64 = PGP.GetFingerprint64(Model.UserSettings.PGPSignature);
pgpFingerprint = PGP.GetFingerprint(Model.SecuritySettings.PGPSignature);
pgpFingerprint64 = PGP.GetFingerprint64(Model.SecuritySettings.PGPSignature);
}

<div class="row text-center">
@@ -58,7 +58,7 @@
<br />
<div class="row">
<div class="col-sm-12">
<textarea class="form-control wmd-input" name="pgpKeyBlock" id="pgpKeyBlock" title="Public Key" rows="10" onClick="SelectAll('pgpKeyBlock');" readonly>@Model.UserSettings.PGPSignature</textarea>
<textarea class="form-control wmd-input" name="pgpKeyBlock" id="pgpKeyBlock" title="Public Key" rows="10" onClick="SelectAll('pgpKeyBlock');" readonly>@Model.SecuritySettings.PGPSignature</textarea>
</div>
</div>
</div>

+ 4
- 4
Teknik/Areas/User/Views/User/Settings.cshtml View File

@@ -71,7 +71,7 @@
</div>
<div class="col-sm-8">
<label for="update_pgp_public_key"><h4>Public Key</h4></label>
<textarea class="form-control" id="update_pgp_public_key" name="update_pgp_public_key" placeholder="Public Key Here" title="enter your pgp public key" rows="15">@Model.UserSettings.PGPSignature</textarea>
<textarea class="form-control" id="update_pgp_public_key" name="update_pgp_public_key" placeholder="Public Key Here" title="enter your pgp public key" rows="15">@Model.SecuritySettings.PGPSignature</textarea>
</div>
</div>
<div class="row">
@@ -79,11 +79,11 @@
<div class="row">
<div class="form-group col-sm-12">
<label for="update_recovery_email"><h4>Recovery Email</h4></label>
<input class="form-control" name="update_recovery_email" id="update_recovery_email" placeholder="user@example.com" title="enter a recovery email." type="text" value="@Model.RecoveryEmail" />
@if (!string.IsNullOrEmpty(Model.RecoveryEmail))
<input class="form-control" name="update_recovery_email" id="update_recovery_email" placeholder="user@example.com" title="enter a recovery email." type="text" value="@Model.SecuritySettings.RecoveryEmail" />
@if (!string.IsNullOrEmpty(Model.SecuritySettings.RecoveryEmail))
{
<p class="form-control-static">
@if (Model.RecoveryVerified)
@if (Model.SecuritySettings.RecoveryVerified)
{
<span class="text-success"><i class="fa fa-check"></i> Verified</span>
}

+ 29
- 14
Teknik/Migrations/Configuration.cs View File

@@ -2,6 +2,7 @@ namespace Teknik.Migrations
{
using Areas.Paste;
using Areas.Upload;
using Areas.Users.Utility;
using Helpers;
using System;
using System.Collections.Generic;
@@ -23,37 +24,49 @@ namespace Teknik.Migrations
protected override void Seed(Models.TeknikEntities context)
{
Config config = Config.Load();
if (config.Migrate)
// Pre-populate with the default stuff
if (!UserHelper.UserExists(context, Constants.SERVERUSER))
{
// Pre-populate with the default stuff
// Create system blog
Areas.Users.Models.User systemUser = new Areas.Users.Models.User();
systemUser.Username = Constants.SERVERUSER;
systemUser.JoinDate = DateTime.Now;
systemUser.LastSeen = DateTime.Now;
systemUser.UserSettings = new Areas.Users.Models.UserSettings();
systemUser.SecuritySettings = new Areas.Users.Models.SecuritySettings();
systemUser.BlogSettings = new Areas.Users.Models.BlogSettings();
systemUser.UploadSettings = new Areas.Users.Models.UploadSettings();
context.Users.AddOrUpdate(systemUser);
context.Users.Add(systemUser);
context.SaveChanges();

Areas.Blog.Models.Blog systemBlog = new Areas.Blog.Models.Blog();
systemBlog.UserId = systemUser.UserId;
systemBlog.BlogId = config.BlogConfig.ServerBlogId;
context.Blogs.AddOrUpdate(systemBlog);
context.Blogs.Add(systemBlog);
context.SaveChanges();
}

Areas.Users.Models.Role adminRole = context.Roles.Where(r => r.Name == "Admin").FirstOrDefault();
if (adminRole == null)
{
// Create roles and groups
Areas.Users.Models.Role adminRole = new Areas.Users.Models.Role();
adminRole = new Areas.Users.Models.Role();
adminRole.Name = "Admin";
adminRole.Description = "Allows complete access to user specific actions";
context.Roles.AddOrUpdate(adminRole);
context.Roles.Add(adminRole);
}

Areas.Users.Models.Role podcastRole = new Areas.Users.Models.Role();
Areas.Users.Models.Role podcastRole = context.Roles.Where(r => r.Name == "Podcast").FirstOrDefault();
if (podcastRole == null)
{
podcastRole = new Areas.Users.Models.Role();
podcastRole.Name = "Podcast";
podcastRole.Description = "Allows create/edit/delete access to podcasts";
context.Roles.AddOrUpdate(podcastRole);
context.Roles.Add(podcastRole);
}

if (context.Groups.Where(g => g.Name == "Administrators").FirstOrDefault() == null)
{
Areas.Users.Models.Group adminGroup = new Areas.Users.Models.Group();
adminGroup.Name = "Administrators";
adminGroup.Description = "System Administrators with full access";
@@ -61,25 +74,27 @@ namespace Teknik.Migrations
adminGroup.Roles.Add(adminRole);
adminGroup.Roles.Add(podcastRole);
context.Groups.AddOrUpdate(adminGroup);
}

if (context.Groups.Where(g => g.Name == "Podcast").FirstOrDefault() == null)
{
Areas.Users.Models.Group podcastGroup = new Areas.Users.Models.Group();
podcastGroup.Name = "Podcast";
podcastGroup.Description = "Podcast team members";
podcastGroup.Roles = new List<Areas.Users.Models.Role>();
podcastGroup.Roles.Add(podcastRole);
context.Groups.AddOrUpdate(podcastGroup);
}

if (context.Groups.Where(g => g.Name == "Member").FirstOrDefault() == null)
{
Areas.Users.Models.Group memberGroup = new Areas.Users.Models.Group();
memberGroup.Name = "Member";
memberGroup.Description = "The default member group with basic permissions";
context.Groups.AddOrUpdate(memberGroup);

context.SaveChanges();
if (config.DatabaseConfig.Migrate)
{
}
}

context.SaveChanges();
}
}
}

+ 19
- 3
Teknik/Models/TeknikEntities.cs View File

@@ -23,12 +23,14 @@ namespace Teknik.Models
public DbSet<Group> Groups { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<TransferType> TransferTypes { get; set; }
public DbSet<RecoveryEmailVerification> RecoveryEmailVerifications { get; set; }
public DbSet<ResetPasswordVerification> ResetPasswordVerifications { get; set; }
// User Settings
public DbSet<UserSettings> UserSettings { get; set; }
public DbSet<SecuritySettings> SecuritySettings { get; set; }
public DbSet<BlogSettings> BlogSettings { get; set; }
public DbSet<UploadSettings> UploadSettings { get; set; }
// Authentication and Sessions
public DbSet<RecoveryEmailVerification> RecoveryEmailVerifications { get; set; }
public DbSet<ResetPasswordVerification> ResetPasswordVerifications { get; set; }
// Blogs
public DbSet<Blog> Blogs { get; set; }
public DbSet<BlogPost> BlogPosts { get; set; }
@@ -55,6 +57,9 @@ namespace Teknik.Models
modelBuilder.Entity<User>()
.HasRequired(a => a.UserSettings)
.WithRequiredPrincipal(a => a.User);
modelBuilder.Entity<User>()
.HasRequired(a => a.SecuritySettings)
.WithRequiredPrincipal(a => a.User);
modelBuilder.Entity<User>()
.HasRequired(a => a.BlogSettings)
.WithRequiredPrincipal(a => a.User);
@@ -62,13 +67,23 @@ namespace Teknik.Models
.HasRequired(a => a.UploadSettings)
.WithRequiredPrincipal(a => a.User);

modelBuilder.Entity<UserSettings>()
.HasRequired(a => a.SecuritySettings)
.WithRequiredPrincipal(a => a.UserSettings);
modelBuilder.Entity<UserSettings>()
.HasRequired(a => a.BlogSettings)
.WithRequiredPrincipal(a => a.UserSettings);
modelBuilder.Entity<UserSettings>()
.HasRequired(a => a.UploadSettings)
.WithRequiredPrincipal(a => a.UserSettings);

modelBuilder.Entity<SecuritySettings>()
.HasRequired(a => a.BlogSettings)
.WithRequiredPrincipal(a => a.SecuritySettings);
modelBuilder.Entity<SecuritySettings>()
.HasRequired(a => a.UploadSettings)
.WithRequiredPrincipal(a => a.SecuritySettings);

modelBuilder.Entity<BlogSettings>()
.HasRequired(a => a.UploadSettings)
.WithRequiredPrincipal(a => a.BlogSettings);
@@ -101,6 +116,7 @@ namespace Teknik.Models
modelBuilder.Entity<ResetPasswordVerification>().ToTable("ResetPasswordVerifications");
// User Settings
modelBuilder.Entity<UserSettings>().ToTable("Users");
modelBuilder.Entity<SecuritySettings>().ToTable("Users");
modelBuilder.Entity<BlogSettings>().ToTable("Users");
modelBuilder.Entity<UploadSettings>().ToTable("Users");
// Blogs

+ 1
- 0
Teknik/Teknik.csproj View File

@@ -211,6 +211,7 @@
<Compile Include="Areas\User\Models\BlogSettings.cs" />
<Compile Include="Areas\User\Models\ResetPasswordVerification.cs" />
<Compile Include="Areas\User\Models\RecoveryEmailVerification.cs" />
<Compile Include="Areas\User\Models\SecuritySettings.cs" />
<Compile Include="Models\TransferTypes.cs" />
<Compile Include="Areas\User\Models\UploadSettings.cs" />
<Compile Include="Areas\User\Models\UserSettings.cs" />

Loading…
Cancel
Save