diff --git a/BillingService/Program.cs b/BillingService/Program.cs index 61b8bbb..076da8f 100644 --- a/BillingService/Program.cs +++ b/BillingService/Program.cs @@ -50,7 +50,7 @@ namespace Teknik.BillingService if (options.SyncSubscriptions) { // Sync subscription information - SyncSubscriptions(config, db); + SyncSubscriptions(config, db).Wait(); } } diff --git a/IdentityServer/ApplicationDbContext.cs b/IdentityServer/ApplicationDbContext.cs index 9053c84..a4da233 100644 --- a/IdentityServer/ApplicationDbContext.cs +++ b/IdentityServer/ApplicationDbContext.cs @@ -36,5 +36,10 @@ namespace Teknik.IdentityServer } } } + + public bool Exists(T entity) where T : class + { + return this.Set().Local.Any(e => e == entity); + } } } \ No newline at end of file diff --git a/IdentityServer/Controllers/ManageController.cs b/IdentityServer/Controllers/ManageController.cs index 18c66ed..ebf5596 100644 --- a/IdentityServer/Controllers/ManageController.cs +++ b/IdentityServer/Controllers/ManageController.cs @@ -731,7 +731,7 @@ namespace Teknik.IdentityServer.Controllers } [HttpGet] - public async Task GetAuthTokens(string username) + public async Task GetAuthTokens(string username, [FromServices] ApplicationDbContext dbContext) { if (string.IsNullOrEmpty(username)) return new JsonResult(new { success = false, message = "Username is required" }); @@ -739,6 +739,9 @@ namespace Teknik.IdentityServer.Controllers var foundUser = await GetCachedUser(username); if (foundUser != null) { + if (!dbContext.Exists(foundUser)) + dbContext.Attach(foundUser); + var authTokens = foundUser.AuthTokens.Select(t => new { authTokenId = t.AuthTokenId, name = t.Name, token = t.Token, lastUsed = t.LastUsed }).ToList(); return new JsonResult(new { success = true, data = authTokens }); } @@ -746,15 +749,18 @@ namespace Teknik.IdentityServer.Controllers } [HttpPost] - public IActionResult CreateAuthToken(CreateAuthTokenModel model, [FromServices] ApplicationDbContext dbContext) + public async Task CreateAuthToken(CreateAuthTokenModel model, [FromServices] ApplicationDbContext dbContext) { if (string.IsNullOrEmpty(model.Username)) return new JsonResult(new { success = false, message = "Username is required" }); - var foundUser = dbContext.Users.FirstOrDefault(u => u.UserName == model.Username); + var foundUser = await GetCachedUser(model.Username); if (foundUser != null) { + if (!dbContext.Exists(foundUser)) + dbContext.Attach(foundUser); + // Generate a unique token var token = StringHelper.RandomString(40, "abcdefghjkmnpqrstuvwxyz1234567890"); while (dbContext.AuthTokens.FirstOrDefault(t => t.Token == token) != null) diff --git a/IdentityServer/_ViewImports.cshtml b/IdentityServer/_ViewImports.cshtml index d9b51d8..899d1c9 100644 --- a/IdentityServer/_ViewImports.cshtml +++ b/IdentityServer/_ViewImports.cshtml @@ -4,7 +4,7 @@ @using Teknik.Utilities @using Teknik.Utilities.TagHelpers -@inject Microsoft.AspNetCore.Hosting.IHostingEnvironment HostingEnvironment +@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment @inject Config Config @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/Teknik/Areas/Help/Controllers/HelpController.cs b/Teknik/Areas/Help/Controllers/HelpController.cs index 1877b64..72dd790 100644 --- a/Teknik/Areas/Help/Controllers/HelpController.cs +++ b/Teknik/Areas/Help/Controllers/HelpController.cs @@ -111,7 +111,7 @@ namespace Teknik.Areas.Help.Controllers } [AllowAnonymous] - public async Task Upload() + public IActionResult Upload() { ViewBag.Title = "Upload Service Help"; UploadHelpViewModel model = new UploadHelpViewModel(); diff --git a/Teknik/Attributes/TrackDownloadAttribute.cs b/Teknik/Attributes/TrackDownloadAttribute.cs index b588e26..8cd8963 100644 --- a/Teknik/Attributes/TrackDownloadAttribute.cs +++ b/Teknik/Attributes/TrackDownloadAttribute.cs @@ -53,7 +53,10 @@ namespace Teknik.Attributes // Fire and forget. Don't need to wait for it. _queue.QueueBackgroundWorkItem(async token => { - Tracking.Tracking.TrackDownload(filterContext.HttpContext, _config, userAgent, clientIp, url, urlReferrer); + await Task.Run(() => + { + Tracking.Tracking.TrackDownload(filterContext.HttpContext, _config, userAgent, clientIp, url, urlReferrer); + }); }); } } diff --git a/Teknik/Controllers/DefaultController.cs b/Teknik/Controllers/DefaultController.cs index b617754..b972493 100644 --- a/Teknik/Controllers/DefaultController.cs +++ b/Teknik/Controllers/DefaultController.cs @@ -97,7 +97,7 @@ namespace Teknik.Controllers using (var writer = new StringWriter()) { - string path = (new Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath; + string path = (new Uri(Assembly.GetExecutingAssembly().Location)).AbsolutePath; ViewEngineResult viewResult = viewEngine.GetView(path, viewName, false); diff --git a/Utilities/Cryptography/AES.cs b/Utilities/Cryptography/AES.cs index 5282d44..9764e37 100644 --- a/Utilities/Cryptography/AES.cs +++ b/Utilities/Cryptography/AES.cs @@ -21,7 +21,7 @@ namespace Teknik.Utilities.Cryptography } } - public static byte[] Encrypt(RijndaelManaged cipher, byte[] value) + public static byte[] Encrypt(Aes cipher, byte[] value) { byte[] encryptedBytes; using (var encryptor = cipher.CreateEncryptor()) @@ -37,7 +37,7 @@ namespace Teknik.Utilities.Cryptography return encryptedBytes; } - public static byte[] Decrypt(RijndaelManaged cipher, byte[] value) + public static byte[] Decrypt(Aes cipher, byte[] value) { byte[] decryptedBytes; using (var decryptor = cipher.CreateDecryptor()) @@ -53,9 +53,9 @@ namespace Teknik.Utilities.Cryptography return decryptedBytes; } - public static RijndaelManaged CreateCipher(byte[] key, byte[] iv, int keyLength, int blockSize, int feedbackSize, CipherMode mode, PaddingMode paddingMode) + public static Aes CreateCipher(byte[] key, byte[] iv, int keyLength, int blockSize, int feedbackSize, CipherMode mode, PaddingMode paddingMode) { - RijndaelManaged cipher = new RijndaelManaged(); + Aes cipher = Aes.Create(); cipher.Mode = mode; cipher.Padding = paddingMode; cipher.Key = key; diff --git a/Utilities/Cryptography/Aes128CFB.cs b/Utilities/Cryptography/Aes128CFB.cs index 7384346..c5c7a66 100644 --- a/Utilities/Cryptography/Aes128CFB.cs +++ b/Utilities/Cryptography/Aes128CFB.cs @@ -60,7 +60,7 @@ namespace Teknik.Utilities.Cryptography public static void ProcessCipher(bool encrypt, byte[] text, byte[] key, byte[] iv, int blockSize, int keySize, ref byte[] output, int offset) { - using (var cipher = new RijndaelManaged()) + using (var cipher = Aes.Create()) { cipher.BlockSize = blockSize; cipher.KeySize = keySize; diff --git a/Utilities/Cryptography/AesCounterMode.cs b/Utilities/Cryptography/AesCounterMode.cs index b5264f7..f26b92b 100644 --- a/Utilities/Cryptography/AesCounterMode.cs +++ b/Utilities/Cryptography/AesCounterMode.cs @@ -8,7 +8,7 @@ namespace Teknik.Utilities.Cryptography // Internal Variables private const int _BlockSize = 16; private readonly byte[] _InitialCounter; - private readonly AesManaged _Algo; + private readonly Aes _Algo; public AesCounterMode() : this(new byte[_BlockSize]) { } @@ -20,11 +20,9 @@ namespace Teknik.Utilities.Cryptography initialCounter.Length, _BlockSize)); // Generate a new instance of the Aes Algorithm in ECB mode with no padding - _Algo = new AesManaged - { - Mode = CipherMode.ECB, - Padding = PaddingMode.None - }; + _Algo = Aes.Create(); + _Algo.Mode = CipherMode.ECB; + _Algo.Padding = PaddingMode.None; // Set the internal variables _InitialCounter = initialCounter; diff --git a/Utilities/Cryptography/SHA256.cs b/Utilities/Cryptography/SHA256.cs index ac7e7f8..ac4b96a 100644 --- a/Utilities/Cryptography/SHA256.cs +++ b/Utilities/Cryptography/SHA256.cs @@ -15,7 +15,7 @@ namespace Teknik.Utilities.Cryptography public static string Hash(byte[] value) { - HashAlgorithm hash = new SHA256CryptoServiceProvider(); + var hash = System.Security.Cryptography.SHA256.Create(); byte[] hashBytes = hash.ComputeHash(value); return Convert.ToBase64String(hashBytes); @@ -23,20 +23,20 @@ namespace Teknik.Utilities.Cryptography public static byte[] Hash(Stream value) { - HashAlgorithm hash = new SHA256CryptoServiceProvider(); + var hash = System.Security.Cryptography.SHA256.Create(); return hash.ComputeHash(value); } public static string Hash(string value, string salt1, string salt2) { - SHA256Managed hash = new SHA256Managed(); + var hash = System.Security.Cryptography.SHA256.Create(); // gen salt2 hash byte[] dataSalt2 = Encoding.UTF8.GetBytes(salt2); byte[] salt2Bytes = hash.ComputeHash(dataSalt2); string salt2Str = string.Empty; foreach (byte x in salt2Bytes) { - salt2Str += String.Format("{0:x2}", x); + salt2Str += string.Format("{0:x2}", x); } string dataStr = salt1 + value + salt2Str; string sha1Str = SHA1.Hash(dataStr); @@ -45,19 +45,9 @@ namespace Teknik.Utilities.Cryptography string hashString = string.Empty; foreach (byte x in valueBytes) { - hashString += String.Format("{0:x2}", x); + hashString += string.Format("{0:x2}", x); } return hashString; } - - public static System.Security.Cryptography.SHA256 CreateHashAlgorithm() - { - if (CryptoConfig.AllowOnlyFipsAlgorithms) - { - return new SHA256CryptoServiceProvider(); - } - - return new SHA256Managed(); - } } } diff --git a/Utilities/StringHelper.cs b/Utilities/StringHelper.cs index 9e220bd..127840c 100644 --- a/Utilities/StringHelper.cs +++ b/Utilities/StringHelper.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using System.Text; namespace Teknik.Utilities @@ -21,7 +22,7 @@ namespace Teknik.Utilities // Guid.NewGuid and System.Random are not particularly random. By using a // cryptographically-secure random number generator, the caller is always // protected, regardless of use. - using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider()) + using (var rng = RandomNumberGenerator.Create()) { var result = new StringBuilder(); var buf = new byte[128];