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

- Added client management to user's settings page.

- Cleaned up identity server pages.
- Added paste migration to service worker.
This commit is contained in:
Uncled1023 2019-01-12 15:06:55 -08:00
parent 933fb9d4cd
commit 179a27dd26
41 changed files with 1442 additions and 3297 deletions

View File

@ -17,6 +17,12 @@ label {
position: relative;
top: -10px;
}
.abc-checkbox label {
display: inline-block !important;
padding-left: 10px !important;
}
.logged-out iframe {
display: none;
width: 0;

View File

@ -2,6 +2,7 @@
using IdentityServer4.Stores;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using Teknik.Configuration;
using Teknik.IdentityServer.Models;
@ -42,7 +43,7 @@ namespace Teknik.IdentityServer.Controllers
return View("Index", vm);
}
return View("Error");
throw new ApplicationException($"Unable to load consent view model.");
}
/// <summary>
@ -69,7 +70,7 @@ namespace Teknik.IdentityServer.Controllers
return View("Index", result.ViewModel);
}
return View("Error");
throw new ApplicationException($"Unable to load consent view model.");
}
}
}

View File

@ -3,6 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IdentityServer4;
using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Entities;
using IdentityServer4.EntityFramework.Mappers;
using IdentityServer4.Models;
using IdentityServer4.Stores;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
@ -11,6 +17,7 @@ using Teknik.Configuration;
using Teknik.IdentityServer.Models;
using Teknik.IdentityServer.Models.Manage;
using Teknik.Logging;
using Teknik.Utilities;
namespace Teknik.IdentityServer.Controllers
{
@ -400,6 +407,115 @@ namespace Teknik.IdentityServer.Controllers
return new JsonResult(new { success = false, message = "User does not exist." });
}
[HttpGet]
public async Task<IActionResult> GetClient(string username, string clientId, [FromServices] IClientStore clientStore, [FromServices] ConfigurationDbContext configContext)
{
if (string.IsNullOrEmpty(username))
return new JsonResult(new { success = false, message = "Username is required" });
if (string.IsNullOrEmpty(clientId))
return new JsonResult(new { success = false, message = "Client Id is required" });
var client = configContext.Clients.FirstOrDefault(c =>
c.ClientId == clientId &&
c.Properties.Exists(p =>
p.Key == "username" &&
p.Value.ToLower() == username.ToLower())
);
if (client != null)
{
var foundClient = await clientStore.FindClientByIdAsync(client.ClientId);
return new JsonResult(new { success = true, data = foundClient });
}
return new JsonResult(new { success = false, message = "Client does not exist." });
}
[HttpGet]
public async Task<IActionResult> GetClients(string username, [FromServices] IClientStore clientStore, [FromServices] ConfigurationDbContext configContext)
{
if (string.IsNullOrEmpty(username))
return new JsonResult(new { success = false, message = "Username is required" });
var foundClientIds = configContext.Clients.Where(c =>
c.Properties.Exists(p =>
p.Key == "username" &&
p.Value.ToLower() == username.ToLower())
).Select(c => c.ClientId);
var clients = new List<IdentityServer4.Models.Client>();
foreach (var clientId in foundClientIds)
{
var foundClient = await clientStore.FindClientByIdAsync(clientId);
if (foundClient != null)
clients.Add(foundClient);
}
return new JsonResult(new { success = true, data = clients });
}
[HttpPost]
public IActionResult CreateClient(CreateClientModel model, [FromServices] ConfigurationDbContext configContext)
{
var clientId = StringHelper.RandomString(20, "abcdefghjkmnpqrstuvwxyz1234567890");
var clientSecret = StringHelper.RandomString(40, "abcdefghjkmnpqrstuvwxyz1234567890");
var client = new IdentityServer4.Models.Client
{
Properties = new Dictionary<string, string>()
{
{ "username", model.Username }
},
ClientId = clientId,
ClientName = model.Name,
AllowedGrantTypes = new List<string>()
{
GrantType.AuthorizationCode,
GrantType.ClientCredentials
},
ClientSecrets =
{
new IdentityServer4.Models.Secret(clientSecret.Sha256())
},
RequireConsent = true,
RedirectUris =
{
model.RedirectURI
},
PostLogoutRedirectUris =
{
model.PostLogoutRedirectURI
},
AllowedScopes = model.AllowedScopes,
AllowOfflineAccess = true
};
configContext.Clients.Add(client.ToEntity());
configContext.SaveChanges();
return new JsonResult(new { success = true, data = new { id = clientId, secret = clientSecret } });
}
[HttpPost]
public async Task<IActionResult> DeleteClient(DeleteClientModel model, [FromServices] IClientStore clientStore, [FromServices] ConfigurationDbContext configContext)
{
var foundClient = await clientStore.FindClientByIdAsync(model.ClientId);
if (foundClient != null)
{
configContext.Clients.Remove(foundClient.ToEntity());
configContext.SaveChanges();
return new JsonResult(new { success = true });
}
return new JsonResult(new { success = false, message = "Client does not exist." });
}
private string FormatKey(string unformattedKey)
{
var result = new StringBuilder();

View File

@ -7,5 +7,10 @@ namespace Teknik.IdentityServer.Models.Manage
{
public class CreateClientModel
{
public string Username { get; set; }
public string Name { get; set; }
public string RedirectURI { get; set; }
public string PostLogoutRedirectURI { get; set; }
public ICollection<string> AllowedScopes { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Teknik.IdentityServer.Models.Manage
{
public class DeleteClientModel
{
public string ClientId { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Teknik.IdentityServer.Models.Manage
{
public class GetClientModel
{
public string Username { get; set; }
public string ClientID { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Teknik.IdentityServer.Models.Manage
{
public class GetClientsModel
{
public string Username { get; set; }
}
}

View File

@ -8,10 +8,9 @@
<div class="container">
<div class="row">
<div class="col-md-12 text-center">
<h1>
Logout
<small>You are now logged out</small>
</h1>
<h2>
You are now logged out
</h2>
@if (Model.PostLogoutRedirectUri != null)
{

View File

@ -1,23 +1,30 @@
@model LogoutViewModel
<div class="logout-page">
<div class="page-header">
<h1>Logout</h1>
</div>
<div class="container">
<div class="row">
<div class="col-sm-6">
<p>Would you like to logout of IdentityServer?</p>
<form asp-action="Logout">
<input type="hidden" name="logoutId" value="@Model.LogoutId" />
<fieldset>
<div class="form-group">
<button class="btn btn-primary">Yes</button>
<div class="col-sm-8 col-sm-offset-2 text-center">
<div class="logout-page">
<div class="page-header">
<h1>Logout</h1>
</div>
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<p>Would you like to logout of IdentityServer?</p>
<form asp-action="Logout">
<input type="hidden" name="logoutId" value="@Model.LogoutId" />
<fieldset>
<div class="form-group">
<button class="btn btn-primary">Yes</button>
</div>
</fieldset>
</form>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
<bundle src="js/signout-redirect.min.js" append-version="true"></bundle>
<bundle src="js/signout-redirect.min.js" append-version="true"></bundle>

View File

@ -1,82 +1,86 @@
@model ConsentViewModel
<div class="page-consent">
<div class="row page-header">
<div class="col-sm-10">
@if (Model.ClientLogoUrl != null)
{
<div class="client-logo"><img src="@Model.ClientLogoUrl"></div>
}
<h1>
@Model.ClientName
<small>is requesting your permission</small>
</h1>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-sm-8">
@Html.Partial("_ValidationSummary")
<form asp-action="Index" class="consent-form">
<input type="hidden" asp-for="ReturnUrl" />
<div>Uncheck the permissions you do not wish to grant.</div>
@if (Model.IdentityScopes.Any())
{
<div class="panel panel-default consent-buttons">
<div class="panel-heading">
<span class="glyphicon glyphicon-user"></span>
Personal Information
</div>
<ul class="list-group">
@foreach (var scope in Model.IdentityScopes)
{
@Html.Partial("_ScopeListItem", scope)
}
</ul>
<div class="col-sm-12 text-center">
<div class="page-consent">
<div class="row page-header">
<div class="col-sm-10 col-sm-offset-1">
@if (Model.ClientLogoUrl != null)
{
<div class="client-logo"><img src="@Model.ClientLogoUrl"></div>
}
<h1>
@Model.ClientName
<small>is requesting your permission</small>
</h1>
</div>
}
@if (Model.ResourceScopes.Any())
{
<div class="panel panel-default">
<div class="panel-heading">
<span class="glyphicon glyphicon-tasks"></span>
Application Access
</div>
<ul class="list-group">
@foreach (var scope in Model.ResourceScopes)
{
@Html.Partial("_ScopeListItem", scope)
}
</ul>
</div>
}
@if (Model.AllowRememberConsent)
{
<div class="consent-remember">
<label>
<input class="consent-scopecheck" asp-for="RememberConsent" />
<strong>Remember My Decision</strong>
</label>
</div>
}
<div class="consent-buttons">
<button name="button" value="yes" class="btn btn-primary" autofocus>Yes, Allow</button>
<button name="button" value="no" class="btn">No, Do Not Allow</button>
@if (Model.ClientUrl != null)
{
<a class="pull-right btn btn-default" target="_blank" href="@Model.ClientUrl">
<span class="glyphicon glyphicon-info-sign"></span>
<strong>@Model.ClientName</strong>
</a>
}
</div>
</form>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
@await Html.PartialAsync("_ValidationSummary")
<form asp-action="Index" class="consent-form">
<input type="hidden" asp-for="ReturnUrl" />
<div>Uncheck the permissions you do not wish to grant.</div>
@if (Model.IdentityScopes.Any())
{
<div class="panel panel-default consent-buttons">
<div class="panel-heading">
<span class="glyphicon glyphicon-user"></span>
Personal Information
</div>
<ul class="list-group">
@foreach (var scope in Model.IdentityScopes)
{
@await Html.PartialAsync("_ScopeListItem", scope)
}
</ul>
</div>
}
@if (Model.ResourceScopes.Any())
{
<div class="panel panel-default">
<div class="panel-heading">
<span class="glyphicon glyphicon-tasks"></span>
Application Access
</div>
<ul class="list-group">
@foreach (var scope in Model.ResourceScopes)
{
@await Html.PartialAsync("_ScopeListItem", scope)
}
</ul>
</div>
}
@if (Model.AllowRememberConsent)
{
<div class="consent-remember abc-checkbox">
<input class="consent-scopecheck" asp-for="RememberConsent" />
<label asp-for="RememberConsent"><strong>Remember My Decision</strong></label>
</div>
}
<div class="consent-buttons">
<button name="button" value="yes" class="btn btn-primary" autofocus>Yes, Allow</button>
<button name="button" value="no" class="btn">No, Do Not Allow</button>
@if (Model.ClientUrl != null)
{
<a class="pull-right btn btn-default" target="_blank" href="@Model.ClientUrl">
<span class="glyphicon glyphicon-info-sign"></span>
<strong>@Model.ClientName</strong>
</a>
}
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,30 +1,30 @@
@model ScopeViewModel
<li class="list-group-item">
<label>
<input class="consent-scopecheck"
type="checkbox"
<li class="list-group-item abc-checkbox">
@if (Model.Required)
{
<input type="hidden"
name="ScopesConsented"
id="scopes_@Model.Name"
value="@Model.Name"
checked="@Model.Checked"
disabled="@Model.Required" />
@if (Model.Required)
{
<input type="hidden"
name="ScopesConsented"
value="@Model.Name" />
}
value="@Model.Name" />
}
<input class="consent-scopecheck"
type="checkbox"
name="ScopesConsented"
id="scopes_@Model.Name"
value="@Model.Name"
checked="@Model.Checked"
disabled="@Model.Required" />
<label for="ScopesConsented">
<strong>@Model.DisplayName</strong>
@if (Model.Emphasize)
{
<span class="glyphicon glyphicon-exclamation-sign"></span>
}
@if (Model.Required)
{
<span><em>(required)</em></span>
}
</label>
@if (Model.Required)
{
<span><em>(required)</em></span>
}
@if (Model.Description != null)
{
<div class="consent-description">

View File

@ -1,79 +1,85 @@
@model GrantsViewModel
<div class="grants">
<div class="row page-header">
<div class="col-sm-10">
<h1>
Client Application Access
</h1>
<div>Below is the list of applications you have given access to and the names of the resources they have access to.</div>
<div class="container">
<div class="row">
<div class="col-md-12 text-center">
<div class="grants">
<div class="row page-header">
<div class="col-sm-12">
<h1>
Client Application Access
</h1>
<div>Below is the list of applications you have given access to and the names of the resources they have access to.</div>
</div>
</div>
@if (Model.Grants.Any() == false)
{
<div class="row">
<div class="col-sm-8">
<div class="alert alert-info">
You have not given access to any applications
</div>
</div>
</div>
}
else
{
foreach (var grant in Model.Grants)
{
<div class="row grant">
<div class="col-sm-2">
@if (grant.ClientLogoUrl != null)
{
<img src="@grant.ClientLogoUrl">
}
</div>
<div class="col-sm-8">
<div class="clientname">@grant.ClientName</div>
<div>
<span class="created">Created:</span> @grant.Created.ToString("yyyy-MM-dd")
</div>
@if (grant.Expires.HasValue)
{
<div>
<span class="expires">Expires:</span> @grant.Expires.Value.ToString("yyyy-MM-dd")
</div>
}
@if (grant.IdentityGrantNames.Any())
{
<div>
<div class="granttype">Identity Grants</div>
<ul>
@foreach (var name in grant.IdentityGrantNames)
{
<li>@name</li>
}
</ul>
</div>
}
@if (grant.ApiGrantNames.Any())
{
<div>
<div class="granttype">API Grants</div>
<ul>
@foreach (var name in grant.ApiGrantNames)
{
<li>@name</li>
}
</ul>
</div>
}
</div>
<div class="col-sm-2">
<form asp-action="Revoke">
<input type="hidden" name="clientId" value="@grant.ClientId">
<button class="btn btn-danger">Revoke Access</button>
</form>
</div>
</div>
}
}
</div>
</div>
</div>
@if (Model.Grants.Any() == false)
{
<div class="row">
<div class="col-sm-8">
<div class="alert alert-info">
You have not given access to any applications
</div>
</div>
</div>
}
else
{
foreach (var grant in Model.Grants)
{
<div class="row grant">
<div class="col-sm-2">
@if (grant.ClientLogoUrl != null)
{
<img src="@grant.ClientLogoUrl">
}
</div>
<div class="col-sm-8">
<div class="clientname">@grant.ClientName</div>
<div>
<span class="created">Created:</span> @grant.Created.ToString("yyyy-MM-dd")
</div>
@if (grant.Expires.HasValue)
{
<div>
<span class="expires">Expires:</span> @grant.Expires.Value.ToString("yyyy-MM-dd")
</div>
}
@if (grant.IdentityGrantNames.Any())
{
<div>
<div class="granttype">Identity Grants</div>
<ul>
@foreach (var name in grant.IdentityGrantNames)
{
<li>@name</li>
}
</ul>
</div>
}
@if (grant.ApiGrantNames.Any())
{
<div>
<div class="granttype">API Grants</div>
<ul>
@foreach (var name in grant.ApiGrantNames)
{
<li>@name</li>
}
</ul>
</div>
}
</div>
<div class="col-sm-2">
<form asp-action="Revoke">
<input type="hidden" name="clientId" value="@grant.ClientId">
<button class="btn btn-danger">Revoke Access</button>
</form>
</div>
</div>
}
}
</div>

View File

@ -27,6 +27,13 @@
where you can find metadata and links to all the endpoints, key material, etc.
</p>
</div>
@if (User.Identity.IsAuthenticated)
{
<div class="col-md-10 col-md-offset-1">
<a class="btn btn-default" href="@Url.Action("Index", "Grants")">View Granted Clients</a>
<a class="btn btn-default" href="@Url.Action("Logout", "Account")">Logout</a>
</div>
}
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace ServiceWorker
namespace Teknik.ServiceWorker
{
public class ArgumentOptions
{
@ -16,6 +16,9 @@ namespace ServiceWorker
[Option('s', "scan", Default = false, Required = false, HelpText = "Scan all uploads for viruses")]
public bool ScanUploads { get; set; }
[Option('m', "migrate", Default = false, Required = false, HelpText = "Migrate everything")]
public bool Migrate { get; set; }
// Omitting long name, default --verbose
[Option(HelpText = "Prints all messages to standard output.")]
public bool Verbose { get; set; }

View File

@ -17,7 +17,7 @@ using Teknik.Data;
using Teknik.Utilities;
using Teknik.Utilities.Cryptography;
namespace ServiceWorker
namespace Teknik.ServiceWorker
{
public class Program
{
@ -57,6 +57,13 @@ namespace ServiceWorker
{
ScanUploads(config, db);
}
// Runs the migration
if (options.Migrate)
{
// Run the overall migration calls
TeknikMigration.RunMigration(db, config);
}
}
Output(string.Format("[{0}] Finished Server Maintenance Process.", DateTime.Now));

View File

@ -3,6 +3,8 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RootNamespace>Teknik.ServiceWorker</RootNamespace>
<AssemblyName>Teknik.ServiceWorker</AssemblyName>
</PropertyGroup>
<ItemGroup>

View File

@ -0,0 +1,64 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Teknik.Areas.Paste;
using Teknik.Areas.Paste.Models;
using Teknik.Configuration;
using Teknik.Data;
using Teknik.Utilities;
namespace Teknik.ServiceWorker
{
public static class TeknikMigration
{
public static bool RunMigration(TeknikEntities db, Config config)
{
bool success = false;
MigratePastes(db, config);
return success;
}
public static void MigratePastes(TeknikEntities db, Config config)
{
if (!Directory.Exists(config.PasteConfig.PasteDirectory))
{
Directory.CreateDirectory(config.PasteConfig.PasteDirectory);
}
foreach (var paste in db.Pastes)
{
if (!string.IsNullOrEmpty(paste.Content) && string.IsNullOrEmpty(paste.FileName) && string.IsNullOrEmpty(paste.HashedPassword))
{
// 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 = PasteHelper.GenerateKey(config.PasteConfig.KeySize);
string iv = PasteHelper.GenerateIV(config.PasteConfig.BlockSize);
// Encrypt the contents to the file
PasteHelper.EncryptContents(paste.Content, filePath, null, key, iv, config.PasteConfig.KeySize, config.PasteConfig.ChunkSize);
// Generate a deletion key
paste.DeleteKey = StringHelper.RandomString(config.PasteConfig.DeleteKeyLength);
paste.Key = key;
paste.KeySize = config.PasteConfig.KeySize;
paste.IV = iv;
paste.BlockSize = config.PasteConfig.BlockSize;
paste.FileName = fileName;
paste.Content = string.Empty;
db.Entry(paste).State = EntityState.Modified;
db.SaveChanges();
}
}
}
}
}

View File

@ -68,22 +68,13 @@ namespace Teknik.Areas.Paste
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))
{
paste.HashedPassword = HashPassword(key, password);
keyBytes = AesCounterManaged.CreateKey(password, ivBytes, config.PasteConfig.KeySize);
}
// Encrypt Content
byte[] data = Encoding.Unicode.GetBytes(content);
using (MemoryStream ms = new MemoryStream(data))
{
AesCounterManaged.EncryptToFile(filePath, ms, config.PasteConfig.ChunkSize, keyBytes, ivBytes);
}
// Encrypt the contents to the file
EncryptContents(content, filePath, password, key, iv, config.PasteConfig.KeySize, config.PasteConfig.ChunkSize);
// Generate a deletion key
string delKey = StringHelper.RandomString(config.PasteConfig.DeleteKeyLength);
@ -127,5 +118,24 @@ namespace Teknik.Areas.Paste
{
return SHA384.Hash(key, password).ToHex();
}
public static void EncryptContents(string content, string filePath, string password, string key, string iv, int keySize, int chunkSize)
{
byte[] ivBytes = Encoding.Unicode.GetBytes(iv);
byte[] keyBytes = AesCounterManaged.CreateKey(key, ivBytes, keySize);
// Set the hashed password if one is provided and modify the key
if (!string.IsNullOrEmpty(password))
{
keyBytes = AesCounterManaged.CreateKey(password, ivBytes, keySize);
}
// Encrypt Content
byte[] data = Encoding.Unicode.GetBytes(content);
using (MemoryStream ms = new MemoryStream(data))
{
AesCounterManaged.EncryptToFile(filePath, ms, chunkSize, keyBytes, ivBytes);
}
}
}
}

View File

@ -35,6 +35,7 @@ using IdentityModel;
using System.Security.Cryptography;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Http;
using IdentityServer4.Models;
namespace Teknik.Areas.Users.Controllers
{
@ -406,22 +407,23 @@ namespace Teknik.Areas.Users.Controllers
return new StatusCodeResult(StatusCodes.Status403Forbidden);
}
public IActionResult AccessTokenSettings()
public async Task<IActionResult> DeveloperSettings()
{
string username = User.Identity.Name;
User user = UserHelper.GetUser(_dbContext, username);
if (user != null)
{
ViewBag.Title = "Access Token Settings - " + _config.Title;
ViewBag.Description = "Your " + _config.Title + " Access Token Settings";
ViewBag.Title = "Developer Settings - " + _config.Title;
ViewBag.Description = "Your " + _config.Title + " Developer Settings";
APIClientSettingsViewModel model = new APIClientSettingsViewModel();
model.Page = "AccessTokens";
DeveloperSettingsViewModel model = new DeveloperSettingsViewModel();
model.Page = "Developer";
model.UserID = user.UserId;
model.Username = user.Username;
model.AuthTokens = new List<AuthTokenViewModel>();
model.Clients = new List<ClientViewModel>();
//foreach (AuthToken token in user.AuthTokens)
//{
// AuthTokenViewModel tokenModel = new AuthTokenViewModel();
@ -432,7 +434,20 @@ namespace Teknik.Areas.Users.Controllers
// model.AuthTokens.Add(tokenModel);
//}
return View("/Areas/User/Views/User/Settings/AccessTokenSettings.cshtml", model);
Client[] clients = await IdentityHelper.GetClients(_config, username);
foreach (Client client in clients)
{
model.Clients.Add(new ClientViewModel()
{
Id = client.ClientId,
Name = client.ClientName,
RedirectURI = string.Join(',', client.RedirectUris),
PostLogoutRedirectURI = string.Join(',', client.PostLogoutRedirectUris),
AllowedScopes = client.AllowedScopes
});
}
return View("/Areas/User/Views/User/Settings/DeveloperSettings.cshtml", model);
}
return new StatusCodeResult(StatusCodes.Status403Forbidden);
@ -1211,6 +1226,58 @@ namespace Teknik.Areas.Users.Controllers
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateClient(string name, string redirectUri, string logoutUri, [FromServices] ICompositeViewEngine viewEngine)
{
try
{
// Validate the code with the identity server
var result = await IdentityHelper.CreateClient(_config, User.Identity.Name, name, redirectUri, logoutUri, "openid", "teknik-api.read", "teknik-api.write");
if (result.Success)
{
var client = (JObject)result.Data;
ClientViewModel model = new ClientViewModel();
model.Id = client["id"].ToString();
model.Name = name;
model.RedirectURI = redirectUri;
model.PostLogoutRedirectURI = logoutUri;
string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/User/Views/User/Settings/ClientView.cshtml", model);
return Json(new { result = true, clientId = client["id"], secret = client["secret"], html = renderedView });
}
return Json(new { error = result.Message });
}
catch (Exception ex)
{
return Json(new { error = ex.GetFullMessage(true) });
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteClient(string clientId)
{
try
{
// Validate the code with the identity server
var result = await IdentityHelper.DeleteClient(_config, clientId);
if (result.Success)
{
return Json(new { result = true });
}
return Json(new { error = result.Message });
}
catch (Exception ex)
{
return Json(new { error = ex.GetFullMessage(true) });
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult CreateInviteCodeLink(int inviteCodeId)

View File

@ -1,4 +1,5 @@
using IdentityModel.Client;
using IdentityServer4.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
@ -324,5 +325,57 @@ namespace Teknik.Areas.Users.Utility
}
throw new Exception(response.Message);
}
public static async Task<Client> GetClient(Config config, string username, string clientId)
{
var manageUrl = CreateUrl(config, $"Manage/GetClient?username={username}&clientId={clientId}");
var result = await Get(config, manageUrl);
if (result.Success)
{
return (Client)result.Data;
}
throw new Exception(result.Message);
}
public static async Task<Client[]> GetClients(Config config, string username)
{
var manageUrl = CreateUrl(config, $"Manage/GetClients?username={username}");
var result = await Get(config, manageUrl);
if (result.Success)
{
return ((JArray)result.Data).ToObject<Client[]>();
}
throw new Exception(result.Message);
}
public static async Task<IdentityResult> CreateClient(Config config, string username, string name, string redirectURI, string postLogoutRedirectURI, params string[] allowedScopes)
{
var manageUrl = CreateUrl(config, $"Manage/CreateClient");
var response = await Post(config, manageUrl,
new
{
username = username,
name = name,
redirectURI = redirectURI,
postLogoutRedirectURI = postLogoutRedirectURI,
allowedScopes = allowedScopes
});
return response;
}
public static async Task<IdentityResult> DeleteClient(Config config, string clientId)
{
var manageUrl = CreateUrl(config, $"Manage/DeleteClient");
var response = await Post(config, manageUrl,
new
{
clientId = clientId
});
return response;
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Teknik.ViewModels;
namespace Teknik.Areas.Users.ViewModels
{
public class ClientViewModel : ViewModelBase
{
public string Id { get; set; }
public string Name { get; set; }
public string RedirectURI { get; set; }
public string PostLogoutRedirectURI { get; set; }
public ICollection<string> AllowedScopes { get; set; }
}
}

View File

@ -5,14 +5,16 @@ using System.Threading.Tasks;
namespace Teknik.Areas.Users.ViewModels
{
public class APIClientSettingsViewModel : SettingsViewModel
public class DeveloperSettingsViewModel : SettingsViewModel
{
public List<AuthTokenViewModel> AuthTokens { get; set; }
public List<ClientViewModel> Clients { get; set; }
public APIClientSettingsViewModel()
public DeveloperSettingsViewModel()
{
AuthTokens = new List<AuthTokenViewModel>();
Clients = new List<ClientViewModel>();
}
}
}

View File

@ -0,0 +1,25 @@
@model Teknik.Areas.Users.ViewModels.ClientViewModel
<li class="list-group-item" id="client_@Model.Id">
<div class="btn-group btn-group-sm pull-right" role="group" aria-label="...">
<button type="button" class="btn btn-danger text-danger deleteClient" id="deleteClient_@Model.Id" data-clientId="@Model.Id">Delete</button>
</div>
<h3 class="list-group-item-heading" id="clientName_@Model.Name">@Model.Name</h3>
<div class="list-group-item-text">
<div class="row">
<div class="col-sm-4">
<strong>Client Id</strong>: @Model.Id
</div>
<div class="col-sm-8">
<div class="row">
<div class="col-sm-4"><strong>Redirect Url</strong></div>
<div class="col-sm-8">@Model.RedirectURI</div>
</div>
<div class="row">
<div class="col-sm-4"><strong>Logout Url</strong></div>
<div class="col-sm-8">@Model.PostLogoutRedirectURI</div>
</div>
</div>
</div>
</div>
</li>

View File

@ -1,4 +1,4 @@
@model Teknik.Areas.Users.ViewModels.APIClientSettingsViewModel
@model Teknik.Areas.Users.ViewModels.DeveloperSettingsViewModel
@using Teknik.Areas.Users.ViewModels
@ -7,13 +7,17 @@
}
<script>
var clearTrustedDevicesURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "ClearTrustedDevices" })';
var generateTokenURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "GenerateToken" })';
var revokeAllTokensURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "RevokeAllTokens" })';
var editTokenNameURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditTokenName" })';
var deleteTokenURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "DeleteToken" })';
var createClientURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "CreateClient" })';
var deleteClientURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "DeleteClient" })';
</script>
<!--
<div class="row">
<div class="col-sm-12">
<h2>API Clients</h2>
@ -23,7 +27,7 @@
<div class="row">
<div class="col-sm-12">
<br />
<label for="authTokens"><h4>API Clients</h4></label><span class="pull-right"><button type="button" class="btn btn-default" id="create_client">Create Client</button> <button type="button" class="btn btn-danger" id="revoke_all_clients">Revoke All</button></span>
<label for="authTokens"><h4>API Clients</h4></label><span class="pull-right"><button type="button" class="btn btn-default" id="create_authToken">Create Auth Token</button> <button type="button" class="btn btn-danger" id="revoke_all_authTokens">Revoke All</button></span>
<div id="authTokens" style="overflow-y: auto; max-height: 400px;">
<ul class="list-group" id="apiClientList">
@if (Model.AuthTokens.Any())
@ -41,5 +45,34 @@
</div>
</div>
</div>
-->
<bundle src="js/user.settings.accessTokenSettings.min.js" append-version="true"></bundle>
<div class="row">
<div class="col-sm-12">
<h2>Clients</h2>
<hr />
</div>
</div>
<div class="row">
<div class="col-sm-12">
<br />
<label for="clients"><h4>Clients</h4></label><span class="pull-right"><button type="button" class="btn btn-default" id="create_client">Create Client</button></span>
<div id="clients" style="overflow-y: auto; max-height: 400px;">
<ul class="list-group" id="clientList">
@if (Model.Clients.Any())
{
foreach (ClientViewModel client in Model.Clients)
{
@await Html.PartialAsync("Settings/ClientView", client)
}
}
else
{
<li class="list-group-item text-center" id="noClients">No Clients</li>
}
</ul>
</div>
</div>
</div>
<bundle src="js/user.settings.developer.min.js" append-version="true"></bundle>

View File

@ -14,14 +14,18 @@
<!--left col-->
<div class="panel panel-default">
<ul class="list-group">
<div class="panel-heading text-center"><strong>Settings</strong></div>
<div class="panel-heading text-center"><strong>Personal Settings</strong></div>
<a href="@Url.SubRouteUrl("user", "User.ProfileSettings")" class="list-group-item @(Model.Page == "Profile" ? "active" : string.Empty)">Profile</a>
<a href="@Url.SubRouteUrl("user", "User.AccountSettings")" class="list-group-item @(Model.Page == "Account" ? "active" : string.Empty)">Account</a>
<a href="@Url.SubRouteUrl("user", "User.SecuritySettings")" class="list-group-item @(Model.Page == "Security" ? "active" : string.Empty)">Security</a>
<a href="@Url.SubRouteUrl("user", "User.InviteSettings")" class="list-group-item @(Model.Page == "Invite" ? "active" : string.Empty)">Invite Codes</a>
<a href="@Url.SubRouteUrl("user", "User.BlogSettings")" class="list-group-item @(Model.Page == "Blog" ? "active" : string.Empty)">Blogging</a>
<a href="@Url.SubRouteUrl("user", "User.UploadSettings")" class="list-group-item @(Model.Page == "Upload" ? "active" : string.Empty)">Uploads</a>
<a href="@Url.SubRouteUrl("user", "User.APIClientSettings")" class="list-group-item @(Model.Page == "APIClients" ? "active" : string.Empty)">API Clients</a>
</ul>
</div>
<div class="panel panel-default">
<ul class="list-group">
<a href="@Url.SubRouteUrl("user", "User.DeveloperSettings")" class="list-group-item @(Model.Page == "Developer" ? "active" : string.Empty)">Developer Settings</a>
</ul>
</div>
</div><!--/col-2-->

File diff suppressed because it is too large Load Diff

View File

@ -1,40 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Teknik.Data.Migrations
{
public partial class UserLoginInfo : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
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);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserLogins");
}
}
}

View File

@ -1,789 +0,0 @@
// <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("20181018071735_IdentityAuth")]
partial class IdentityAuth
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.2.0-preview2-35157")
.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<DateTime?>("ExpireDate");
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<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?>("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.RecoveryEmailVerification", b =>
{
b.Property<int>("RecoveryEmailVerificationId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Code")
.HasAnnotation("CaseSensitive", true);
b.Property<DateTime>("DateCreated");
b.Property<int>("UserId");
b.HasKey("RecoveryEmailVerificationId");
b.HasIndex("UserId");
b.ToTable("RecoveryEmailVerifications");
});
modelBuilder.Entity("Teknik.Areas.Users.Models.ResetPasswordVerification", b =>
{
b.Property<int>("ResetPasswordVerificationId")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Code")
.HasAnnotation("CaseSensitive", true);
b.Property<DateTime>("DateCreated");
b.Property<int>("UserId");
b.HasKey("ResetPasswordVerificationId");
b.HasIndex("UserId");
b.ToTable("ResetPasswordVerifications");
});
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.RecoveryEmailVerification", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Teknik.Areas.Users.Models.ResetPasswordVerification", b =>
{
b.HasOne("Teknik.Areas.Users.Models.User", "User")
.WithMany()
.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
}
}
}

View File

@ -1,277 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Teknik.Data.Migrations
{
public partial class IdentityAuth : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AuthTokens");
migrationBuilder.DropTable(
name: "TransferTypes");
migrationBuilder.DropTable(
name: "TrustedDevices");
migrationBuilder.DropTable(
name: "UserRoles");
migrationBuilder.DropTable(
name: "Roles");
migrationBuilder.DropColumn(
name: "AllowTrustedDevices",
table: "Users");
migrationBuilder.DropColumn(
name: "PGPSignature",
table: "Users");
migrationBuilder.DropColumn(
name: "RecoveryEmail",
table: "Users");
migrationBuilder.DropColumn(
name: "RecoveryVerified",
table: "Users");
migrationBuilder.DropColumn(
name: "TwoFactorEnabled",
table: "Users");
migrationBuilder.DropColumn(
name: "TwoFactorKey",
table: "Users");
migrationBuilder.DropColumn(
name: "AccountStatus",
table: "Users");
migrationBuilder.DropColumn(
name: "AccountType",
table: "Users");
migrationBuilder.DropColumn(
name: "HashedPassword",
table: "Users");
migrationBuilder.DropColumn(
name: "JoinDate",
table: "Users");
migrationBuilder.DropColumn(
name: "LastSeen",
table: "Users");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "AllowTrustedDevices",
table: "Users",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<string>(
name: "PGPSignature",
table: "Users",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "RecoveryEmail",
table: "Users",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "RecoveryVerified",
table: "Users",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<bool>(
name: "TwoFactorEnabled",
table: "Users",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<string>(
name: "TwoFactorKey",
table: "Users",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "AccountStatus",
table: "Users",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "AccountType",
table: "Users",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<string>(
name: "HashedPassword",
table: "Users",
nullable: true);
migrationBuilder.AddColumn<DateTime>(
name: "JoinDate",
table: "Users",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.AddColumn<DateTime>(
name: "LastSeen",
table: "Users",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.CreateTable(
name: "AuthTokens",
columns: table => new
{
AuthTokenId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
HashedToken = table.Column<string>(nullable: true),
LastDateUsed = table.Column<DateTime>(nullable: true),
Name = table.Column<string>(nullable: true),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AuthTokens", x => x.AuthTokenId);
table.ForeignKey(
name: "FK_AuthTokens_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Roles",
columns: table => new
{
RoleId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Description = table.Column<string>(nullable: true),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Roles", x => x.RoleId);
});
migrationBuilder.CreateTable(
name: "TransferTypes",
columns: table => new
{
TransferTypeId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
PasteId = table.Column<int>(nullable: true),
Type = table.Column<int>(nullable: false),
UserId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_TransferTypes", x => x.TransferTypeId);
table.ForeignKey(
name: "FK_TransferTypes_Pastes_PasteId",
column: x => x.PasteId,
principalTable: "Pastes",
principalColumn: "PasteId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_TransferTypes_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "TrustedDevices",
columns: table => new
{
TrustedDeviceId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
DateSeen = table.Column<DateTime>(nullable: false),
Name = table.Column<string>(nullable: true),
Token = table.Column<string>(nullable: true),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TrustedDevices", x => x.TrustedDeviceId);
table.ForeignKey(
name: "FK_TrustedDevices_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "UserRoles",
columns: table => new
{
UserRoleId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
RoleId = table.Column<int>(nullable: false),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserRoles", x => x.UserRoleId);
table.ForeignKey(
name: "FK_UserRoles_Roles_RoleId",
column: x => x.RoleId,
principalTable: "Roles",
principalColumn: "RoleId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_UserRoles_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AuthTokens_UserId",
table: "AuthTokens",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_TransferTypes_PasteId",
table: "TransferTypes",
column: "PasteId");
migrationBuilder.CreateIndex(
name: "IX_TransferTypes_UserId",
table: "TransferTypes",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_TrustedDevices_UserId",
table: "TrustedDevices",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_UserRoles_RoleId",
table: "UserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "IX_UserRoles_UserId",
table: "UserRoles",
column: "UserId");
}
}
}

View File

@ -1,733 +0,0 @@
// <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("20181021081119_RemovedVerificationTables")]
partial class RemovedVerificationTables
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.2.0-preview2-35157")
.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<DateTime?>("ExpireDate");
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<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?>("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
}
}
}

View File

@ -1,73 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Teknik.Data.Migrations
{
public partial class RemovedVerificationTables : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "RecoveryEmailVerifications");
migrationBuilder.DropTable(
name: "ResetPasswordVerifications");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "RecoveryEmailVerifications",
columns: table => new
{
RecoveryEmailVerificationId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Code = table.Column<string>(nullable: true),
DateCreated = table.Column<DateTime>(nullable: false),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_RecoveryEmailVerifications", x => x.RecoveryEmailVerificationId);
table.ForeignKey(
name: "FK_RecoveryEmailVerifications_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ResetPasswordVerifications",
columns: table => new
{
ResetPasswordVerificationId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Code = table.Column<string>(nullable: true),
DateCreated = table.Column<DateTime>(nullable: false),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ResetPasswordVerifications", x => x.ResetPasswordVerificationId);
table.ForeignKey(
name: "FK_ResetPasswordVerifications_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_RecoveryEmailVerifications_UserId",
table: "RecoveryEmailVerifications",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_ResetPasswordVerifications_UserId",
table: "ResetPasswordVerifications",
column: "UserId");
}
}
}

View File

@ -1,51 +0,0 @@
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");
}
}
}

View File

@ -10,8 +10,8 @@ using Teknik.Data;
namespace Teknik.Data.Migrations
{
[DbContext(typeof(TeknikEntities))]
[Migration("20181121074110_PasteFiles")]
partial class PasteFiles
[Migration("20181222043715_InitialMigration")]
partial class InitialMigration
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{

View File

@ -0,0 +1,641 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Teknik.Data.Migrations
{
public partial class InitialMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Contact",
columns: table => new
{
ContactId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(nullable: true),
Email = table.Column<string>(nullable: true),
Subject = table.Column<string>(nullable: true),
Message = table.Column<string>(nullable: true),
DateAdded = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Contact", x => x.ContactId);
});
migrationBuilder.CreateTable(
name: "Podcasts",
columns: table => new
{
PodcastId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Episode = table.Column<int>(nullable: false),
Title = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true),
Published = table.Column<bool>(nullable: false),
DatePosted = table.Column<DateTime>(nullable: false),
DatePublished = table.Column<DateTime>(nullable: false),
DateEdited = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Podcasts", x => x.PodcastId);
});
migrationBuilder.CreateTable(
name: "Takedowns",
columns: table => new
{
TakedownId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Requester = table.Column<string>(nullable: true),
RequesterContact = table.Column<string>(nullable: true),
Reason = table.Column<string>(nullable: true),
ActionTaken = table.Column<string>(nullable: true),
DateRequested = table.Column<DateTime>(nullable: false),
DateActionTaken = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Takedowns", x => x.TakedownId);
});
migrationBuilder.CreateTable(
name: "Transactions",
columns: table => new
{
TransactionId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Amount = table.Column<decimal>(type: "decimal(19, 5)", nullable: false),
Currency = table.Column<int>(nullable: false),
Reason = table.Column<string>(nullable: true),
DateSent = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Transactions", x => x.TransactionId);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
UserId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Username = table.Column<string>(nullable: true),
About = table.Column<string>(nullable: true),
Website = table.Column<string>(nullable: true),
Quote = table.Column<string>(nullable: true),
Title = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true),
Encrypt = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.UserId);
});
migrationBuilder.CreateTable(
name: "PodcastFiles",
columns: table => new
{
PodcastFileId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
PodcastId = table.Column<int>(nullable: false),
FileName = table.Column<string>(nullable: true),
Path = table.Column<string>(nullable: true),
ContentType = table.Column<string>(nullable: true),
ContentLength = table.Column<long>(nullable: false),
Size = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PodcastFiles", x => x.PodcastFileId);
table.ForeignKey(
name: "FK_PodcastFiles_Podcasts_PodcastId",
column: x => x.PodcastId,
principalTable: "Podcasts",
principalColumn: "PodcastId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "PodcastTags",
columns: table => new
{
PodcastTagId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
PodcastId = table.Column<int>(nullable: false),
Name = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PodcastTags", x => x.PodcastTagId);
table.ForeignKey(
name: "FK_PodcastTags_Podcasts_PodcastId",
column: x => x.PodcastId,
principalTable: "Podcasts",
principalColumn: "PodcastId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Blogs",
columns: table => new
{
BlogId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Blogs", x => x.BlogId);
table.ForeignKey(
name: "FK_Blogs_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "InviteCodes",
columns: table => new
{
InviteCodeId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Active = table.Column<bool>(nullable: false),
Code = table.Column<string>(nullable: true),
OwnerId = table.Column<int>(nullable: true),
ClaimedUserId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_InviteCodes", x => x.InviteCodeId);
table.ForeignKey(
name: "FK_InviteCodes_Users_ClaimedUserId",
column: x => x.ClaimedUserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_InviteCodes_Users_OwnerId",
column: x => x.OwnerId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Pastes",
columns: table => new
{
PasteId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
UserId = table.Column<int>(nullable: true),
DatePosted = table.Column<DateTime>(nullable: false),
Url = table.Column<string>(nullable: true),
FileName = table.Column<string>(nullable: true),
Content = table.Column<string>(nullable: true),
Title = table.Column<string>(nullable: true),
Syntax = table.Column<string>(nullable: true),
ExpireDate = table.Column<DateTime>(nullable: true),
HashedPassword = table.Column<string>(nullable: true),
Key = table.Column<string>(nullable: true),
KeySize = table.Column<int>(nullable: false),
IV = table.Column<string>(nullable: true),
BlockSize = table.Column<int>(nullable: false),
DeleteKey = table.Column<string>(nullable: true),
Hide = table.Column<bool>(nullable: false),
MaxViews = table.Column<int>(nullable: false),
Views = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Pastes", x => x.PasteId);
table.ForeignKey(
name: "FK_Pastes_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "PodcastComments",
columns: table => new
{
PodcastCommentId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
PodcastId = table.Column<int>(nullable: false),
UserId = table.Column<int>(nullable: false),
DatePosted = table.Column<DateTime>(nullable: false),
DateEdited = table.Column<DateTime>(nullable: false),
Article = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PodcastComments", x => x.PodcastCommentId);
table.ForeignKey(
name: "FK_PodcastComments_Podcasts_PodcastId",
column: x => x.PodcastId,
principalTable: "Podcasts",
principalColumn: "PodcastId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_PodcastComments_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ShortenedUrls",
columns: table => new
{
ShortenedUrlId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
UserId = table.Column<int>(nullable: true),
ShortUrl = table.Column<string>(nullable: true),
OriginalUrl = table.Column<string>(nullable: true),
DateAdded = table.Column<DateTime>(nullable: false),
Views = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ShortenedUrls", x => x.ShortenedUrlId);
table.ForeignKey(
name: "FK_ShortenedUrls_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Uploads",
columns: table => new
{
UploadId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
UserId = table.Column<int>(nullable: true),
DateUploaded = table.Column<DateTime>(nullable: false),
Url = table.Column<string>(nullable: true),
FileName = table.Column<string>(nullable: true),
ContentLength = table.Column<long>(nullable: false),
ContentType = table.Column<string>(nullable: true),
Key = table.Column<string>(nullable: true),
IV = table.Column<string>(nullable: true),
KeySize = table.Column<int>(nullable: false),
BlockSize = table.Column<int>(nullable: false),
DeleteKey = table.Column<string>(nullable: true),
ExpireDate = table.Column<DateTime>(nullable: true),
MaxDownloads = table.Column<int>(nullable: false),
Downloads = table.Column<int>(nullable: false),
Takedown_TakedownId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Uploads", x => x.UploadId);
table.ForeignKey(
name: "FK_Uploads_Takedowns_Takedown_TakedownId",
column: x => x.Takedown_TakedownId,
principalTable: "Takedowns",
principalColumn: "TakedownId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Uploads_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
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.CreateTable(
name: "Vaults",
columns: table => new
{
VaultId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
UserId = table.Column<int>(nullable: true),
Url = table.Column<string>(nullable: true),
Title = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true),
DateCreated = table.Column<DateTime>(nullable: false),
DateEdited = table.Column<DateTime>(nullable: false),
Views = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Vaults", x => x.VaultId);
table.ForeignKey(
name: "FK_Vaults_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "BlogPosts",
columns: table => new
{
BlogPostId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
BlogId = table.Column<int>(nullable: false),
System = table.Column<bool>(nullable: false),
DatePosted = table.Column<DateTime>(nullable: false),
DatePublished = table.Column<DateTime>(nullable: false),
DateEdited = table.Column<DateTime>(nullable: false),
Published = table.Column<bool>(nullable: false),
Title = table.Column<string>(nullable: true),
Article = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_BlogPosts", x => x.BlogPostId);
table.ForeignKey(
name: "FK_BlogPosts_Blogs_BlogId",
column: x => x.BlogId,
principalTable: "Blogs",
principalColumn: "BlogId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "VaultItems",
columns: table => new
{
VaultItemId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
VaultId = table.Column<int>(nullable: false),
Title = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true),
DateAdded = table.Column<DateTime>(nullable: false),
Discriminator = table.Column<string>(nullable: false),
PasteId = table.Column<int>(nullable: true),
UploadId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_VaultItems", x => x.VaultItemId);
table.ForeignKey(
name: "FK_VaultItems_Pastes_PasteId",
column: x => x.PasteId,
principalTable: "Pastes",
principalColumn: "PasteId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_VaultItems_Uploads_UploadId",
column: x => x.UploadId,
principalTable: "Uploads",
principalColumn: "UploadId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_VaultItems_Vaults_VaultId",
column: x => x.VaultId,
principalTable: "Vaults",
principalColumn: "VaultId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "BlogPostComments",
columns: table => new
{
BlogPostCommentId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
BlogPostId = table.Column<int>(nullable: false),
UserId = table.Column<int>(nullable: true),
DatePosted = table.Column<DateTime>(nullable: false),
DateEdited = table.Column<DateTime>(nullable: false),
Article = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_BlogPostComments", x => x.BlogPostCommentId);
table.ForeignKey(
name: "FK_BlogPostComments_BlogPosts_BlogPostId",
column: x => x.BlogPostId,
principalTable: "BlogPosts",
principalColumn: "BlogPostId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_BlogPostComments_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "BlogPostTags",
columns: table => new
{
BlogPostTagId = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
BlogPostId = table.Column<int>(nullable: false),
Name = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_BlogPostTags", x => x.BlogPostTagId);
table.ForeignKey(
name: "FK_BlogPostTags_BlogPosts_BlogPostId",
column: x => x.BlogPostId,
principalTable: "BlogPosts",
principalColumn: "BlogPostId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_BlogPostComments_BlogPostId",
table: "BlogPostComments",
column: "BlogPostId");
migrationBuilder.CreateIndex(
name: "IX_BlogPostComments_UserId",
table: "BlogPostComments",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_BlogPosts_BlogId",
table: "BlogPosts",
column: "BlogId");
migrationBuilder.CreateIndex(
name: "IX_BlogPostTags_BlogPostId",
table: "BlogPostTags",
column: "BlogPostId");
migrationBuilder.CreateIndex(
name: "IX_Blogs_UserId",
table: "Blogs",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_InviteCodes_ClaimedUserId",
table: "InviteCodes",
column: "ClaimedUserId",
unique: true,
filter: "[ClaimedUserId] IS NOT NULL");
migrationBuilder.CreateIndex(
name: "IX_InviteCodes_OwnerId",
table: "InviteCodes",
column: "OwnerId");
migrationBuilder.CreateIndex(
name: "IX_Pastes_UserId",
table: "Pastes",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_PodcastComments_PodcastId",
table: "PodcastComments",
column: "PodcastId");
migrationBuilder.CreateIndex(
name: "IX_PodcastComments_UserId",
table: "PodcastComments",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_PodcastFiles_PodcastId",
table: "PodcastFiles",
column: "PodcastId");
migrationBuilder.CreateIndex(
name: "IX_PodcastTags_PodcastId",
table: "PodcastTags",
column: "PodcastId");
migrationBuilder.CreateIndex(
name: "IX_ShortenedUrls_UserId",
table: "ShortenedUrls",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Uploads_Takedown_TakedownId",
table: "Uploads",
column: "Takedown_TakedownId");
migrationBuilder.CreateIndex(
name: "IX_Uploads_UserId",
table: "Uploads",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_UserLogins_UserId",
table: "UserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_VaultItems_PasteId",
table: "VaultItems",
column: "PasteId");
migrationBuilder.CreateIndex(
name: "IX_VaultItems_UploadId",
table: "VaultItems",
column: "UploadId");
migrationBuilder.CreateIndex(
name: "IX_VaultItems_VaultId",
table: "VaultItems",
column: "VaultId");
migrationBuilder.CreateIndex(
name: "IX_Vaults_UserId",
table: "Vaults",
column: "UserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "BlogPostComments");
migrationBuilder.DropTable(
name: "BlogPostTags");
migrationBuilder.DropTable(
name: "Contact");
migrationBuilder.DropTable(
name: "InviteCodes");
migrationBuilder.DropTable(
name: "PodcastComments");
migrationBuilder.DropTable(
name: "PodcastFiles");
migrationBuilder.DropTable(
name: "PodcastTags");
migrationBuilder.DropTable(
name: "ShortenedUrls");
migrationBuilder.DropTable(
name: "Transactions");
migrationBuilder.DropTable(
name: "UserLogins");
migrationBuilder.DropTable(
name: "VaultItems");
migrationBuilder.DropTable(
name: "BlogPosts");
migrationBuilder.DropTable(
name: "Podcasts");
migrationBuilder.DropTable(
name: "Pastes");
migrationBuilder.DropTable(
name: "Uploads");
migrationBuilder.DropTable(
name: "Vaults");
migrationBuilder.DropTable(
name: "Blogs");
migrationBuilder.DropTable(
name: "Takedowns");
migrationBuilder.DropTable(
name: "Users");
}
}
}

View File

@ -1,86 +0,0 @@
using IdentityServer4;
using IdentityServer4.Configuration;
using IdentityServer4.Models;
using Microsoft.AspNetCore.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Teknik
{
public class IdentityServerConfig
{
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api", "Teknik API")
};
}
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client",
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
// scopes that client has access to
AllowedScopes = { "api" }
},
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api"
},
AllowOfflineAccess = true
}
};
}
public static void SetupIdentityServer(IdentityServerOptions options)
{
RouteData routeData = new RouteData();
routeData.DataTokens.Add("area", "Error");
routeData.Values.Add("controller", "Error");
//routeData.Routers.Add(_router);
}
}
}

View File

@ -660,11 +660,11 @@ namespace Teknik
defaults: new { area = "User", controller = "User", action = "ProfileSettings" }
);
routes.MapSubdomainRoute(
name: "User.AccessTokenSettings",
name: "User.DeveloperSettings",
domains: new List<string>() { config.Host },
subDomains: new List<string>() { "user" },
template: "Settings/AccessTokens",
defaults: new { area = "User", controller = "User", action = "AccessTokenSettings" }
template: "Settings/Developer",
defaults: new { area = "User", controller = "User", action = "DeveloperSettings" }
);
routes.MapSubdomainRoute(
name: "User.InviteSettings",

View File

@ -1,10 +1,80 @@
$(document).ready(function () {
$('#create_client').click(function () {
var name, redirectUri, logoutUri;
bootbox.prompt("Specify a name for this Client", function (result) {
if (result) {
name = result;
bootbox.prompt("Specify the Redirect URI for this Client", function (result) {
if (result) {
redirectUri = result;
bootbox.prompt("Specify the Logout URI for this Client", function (result) {
if (result) {
logoutUri = result;
$.ajax({
type: "POST",
url: createClientURL,
data: AddAntiForgeryToken({ name: name, redirectUri: redirectUri, logoutUri: logoutUri }),
success: function (response) {
if (response.result) {
var dialog = bootbox.dialog({
closeButton: false,
buttons: {
close: {
label: 'Close',
className: 'btn-primary',
callback: function () {
if ($('#noClients')) {
$('#noClients').remove();
}
var item = $(response.result.html);
var deleteBtn = item.find('.deleteClient');
deleteBtn.click(function () {
var clientId = $(this).attr("data-clientId");
deleteClient(clientId);
});
$('#clientList').append(item);
}
}
},
title: "Client Secret",
message: '<label for="clientSecret">Make sure to copy your client secret now.<br />You won\'t be able to see it again!</label><input type="text" class="form-control" id="clientSecret" value="' + response.result.secret + '">',
});
dialog.init(function () {
dialog.find('#authToken').click(function () {
$(this).select();
});
});
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + parseErrorMessage(response) + '</div>');
}
}
});
}
});
}
});
}
});
});
$(".deleteClient").click(function () {
var clientId = $(this).attr("data-clientId");
deleteClient(clientId);
});
$('#create_authToken').click(function () {
bootbox.prompt("Specify a name for this Auth Token", function (result) {
if (result) {
$.ajax({
type: "POST",
url: createClientURL,
url: generateTokenURL,
data: AddAntiForgeryToken({ name: result }),
success: function (response) {
if (response.result) {
@ -57,7 +127,7 @@
});
});
$('#revoke_all_clients').click(function () {
$('#revoke_all_authTokens').click(function () {
bootbox.confirm("Are you sure you want to revoke all your clients?<br /><br />This is <b>irreversable</b> and all applications using these clients will stop working.", function (result) {
if (result) {
$.ajax({
@ -133,3 +203,27 @@ function deleteAuthToken(authTokenId) {
}
});
}
function deleteClient(clientId) {
bootbox.confirm("<h2>Are you sure you want to delete this client?</h2><br /><br />This is <b>irreversable</b> and all applications using these client credentials will stop working.", function (result) {
if (result) {
$.ajax({
type: "POST",
url: deleteClientURL,
data: AddAntiForgeryToken({ clientId: clientId }),
success: function (response) {
if (response.result) {
$('#client_' + clientId).remove();
if ($('#clientList li').length <= 0) {
$('#clientList').html('<li class="list-group-item text-center" id="noClients">No Clients</li>');
}
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + parseErrorMessage(response) + '</div>');
}
}
});
}
});
}

View File

@ -237,9 +237,6 @@ namespace Teknik
// Create and Migrate the database
dbContext.Database.Migrate();
// Run the overall migration calls
TeknikMigration.RunMigration();
// Initiate Logging
loggerFactory.AddLogger(config);

View File

@ -69,6 +69,7 @@
<Folder Include="Areas\TOS\Models\" />
<Folder Include="Areas\User\Controllers\" />
<Folder Include="Controllers\" />
<Folder Include="Data\Migrations\" />
<Folder Include="Views\Shared\" />
<Folder Include="wwwroot\" />
</ItemGroup>
@ -95,6 +96,9 @@
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Areas\User\Views\User\Settings\ClientView.cshtml">
<Pack>$(IncludeRazorContentInPack)</Pack>
</Content>
</ItemGroup>
<ItemGroup>

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Teknik
{
public static class TeknikMigration
{
public static bool RunMigration()
{
bool success = false;
// Transfer User security info to
return success;
}
}
}

View File

@ -139,6 +139,7 @@
"inputFiles": [
"./wwwroot/js/app/lib/Blob.js",
"./wwwroot/lib/file-saver/js/FileSaver.js",
"./wwwroot/lib/bootbox/js/bootbox.js",
"./wwwroot/js/app/Upload/Download.js"
]
},
@ -234,6 +235,12 @@
"./wwwroot/js/app/User/SecuritySettings.js"
]
},
{
"outputFileName": "./wwwroot/js/user.settings.developer.min.js",
"inputFiles": [
"./wwwroot/js/app/User/DeveloperSettings.js"
]
},
{
"outputFileName": "./wwwroot/js/user.settings.upload.min.js",
"inputFiles": [