Testing the push method (TODO coherence between return code a physical result)
This commit is contained in:
@ -1,47 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
public interface IDataProtector
|
||||
{
|
||||
string Protect(string data);
|
||||
string UnProtect(string data);
|
||||
}
|
||||
|
||||
public class DefaultDataProtector : IDataProtector
|
||||
{
|
||||
private byte delta = 145;
|
||||
|
||||
public DefaultDataProtector()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string Protect(string data)
|
||||
{
|
||||
List<Byte> protd = new List<byte>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (byte c in Encoding.UTF8.GetBytes(data))
|
||||
{
|
||||
protd.Add((byte) (c ^ delta));
|
||||
}
|
||||
return System.Convert.ToBase64String(protd.ToArray());
|
||||
}
|
||||
|
||||
public string UnProtect(string data)
|
||||
{
|
||||
if (data==null) return null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<byte> unps = new List<byte>();
|
||||
|
||||
foreach (byte c in System.Convert.FromBase64CharArray(data.ToCharArray(),0,data.Length))
|
||||
{
|
||||
unps.Add((byte) (c ^ delta));
|
||||
}
|
||||
return Encoding.UTF8.GetString(unps.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
public class SourceSettings
|
||||
{
|
||||
private RSA rsa;
|
||||
|
||||
/// <summary>
|
||||
/// Protected API Key
|
||||
/// </summary>
|
||||
@ -22,19 +25,25 @@ namespace isn
|
||||
/// <value></value>
|
||||
public string Alias { get; set; }
|
||||
|
||||
public SourceSettings()
|
||||
{
|
||||
rsa = RSA.Create();
|
||||
}
|
||||
public string GetClearApiKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ApiKey)) return ApiKey;
|
||||
return ProtectedApiKey = Protector.UnProtect(ApiKey);
|
||||
return
|
||||
Encoding.UTF8.GetString(
|
||||
rsa.Decrypt(Encoding.UTF8.GetBytes(ProtectedApiKey),
|
||||
RSAEncryptionPadding.Pkcs1));
|
||||
}
|
||||
|
||||
public void SetApiKey(string key)
|
||||
{
|
||||
ApiKey = key;
|
||||
ProtectedApiKey = Protector.Protect(key);
|
||||
ApiKey = Encoding.UTF8.GetString(
|
||||
rsa.Encrypt(Encoding.UTF8.GetBytes(key),
|
||||
RSAEncryptionPadding.Pkcs1));
|
||||
}
|
||||
|
||||
public static IDataProtector Protector { get; private set ; } = new DefaultDataProtector();
|
||||
}
|
||||
|
||||
public class Settings
|
||||
|
@ -13,6 +13,7 @@ using Microsoft.Extensions.Options;
|
||||
using isnd.Data;
|
||||
using isnd.Entities;
|
||||
using isnd.Data.ApiKeys;
|
||||
using isnd.Interfaces;
|
||||
|
||||
|
||||
namespace isnd.Controllers
|
||||
@ -23,17 +24,20 @@ namespace isnd.Controllers
|
||||
private readonly ApplicationDbContext dbContext;
|
||||
private readonly IsndSettings isndSettings;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
|
||||
private readonly IApiKeyProvider apiKeyProvider;
|
||||
private readonly IDataProtector protector;
|
||||
public ApiKeysController(ApplicationDbContext dbContext,
|
||||
IOptions<IsndSettings> isndSettingsOptions,
|
||||
IDataProtectionProvider provider,
|
||||
UserManager<ApplicationUser> userManager)
|
||||
UserManager<ApplicationUser> userManager,
|
||||
IApiKeyProvider apiKeyProvider
|
||||
)
|
||||
{
|
||||
this.dbContext = dbContext;
|
||||
this.isndSettings = isndSettingsOptions.Value;
|
||||
protector = provider.CreateProtector(isndSettings.ProtectionTitle);
|
||||
_userManager = userManager;
|
||||
this.apiKeyProvider = apiKeyProvider;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@ -57,17 +61,17 @@ namespace isnd.Controllers
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> Create(CreateModel model)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
IQueryable<ApiKey> userKeys = GetUserKeys();
|
||||
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
IQueryable<ApiKey> userKeys = apiKeyProvider.GetUserKeys(User.Identity.Name);
|
||||
if (userKeys.Count() >= isndSettings.MaxUserKeyCount)
|
||||
{
|
||||
ModelState.AddModelError(null, "Maximum key count reached");
|
||||
return View();
|
||||
}
|
||||
ApiKey newKey = new ApiKey { UserId = userid, Name = model.Name,
|
||||
CreationDate = DateTimeOffset.Now.ToUniversalTime() };
|
||||
_ = dbContext.ApiKeys.Add(newKey);
|
||||
_ = await dbContext.SaveChangesAsync();
|
||||
model.UserId = userId;
|
||||
|
||||
ApiKey newKey = await apiKeyProvider.CreateApiKeyAsync(model);
|
||||
|
||||
return View("Details", new DetailModel { Name = newKey.Name,
|
||||
ProtectedValue = protector.Protect(newKey.Id),
|
||||
ApiKey = newKey });
|
||||
@ -79,7 +83,6 @@ namespace isnd.Controllers
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
ApiKey key = await dbContext.ApiKeys.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
|
||||
return View(new DeleteModel { ApiKey = key });
|
||||
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
@ -9,6 +9,8 @@ namespace isnd.Data.ApiKeys
|
||||
[Display(Name = "Key Name")]
|
||||
public string Name { get; set; }
|
||||
public string UserId { get; set; }
|
||||
|
||||
public int ValidityPeriodInDays { get; set; }
|
||||
|
||||
}
|
||||
}
|
13
src/isnd/Interfaces/IApiKeyProvider.cs
Normal file
13
src/isnd/Interfaces/IApiKeyProvider.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using isnd.Data.ApiKeys;
|
||||
|
||||
|
||||
namespace isnd.Interfaces
|
||||
{
|
||||
public interface IApiKeyProvider
|
||||
{
|
||||
Task<ApiKey> CreateApiKeyAsync(CreateModel model);
|
||||
IQueryable<ApiKey> GetUserKeys(string identityName);
|
||||
}
|
||||
}
|
48
src/isnd/Services/ApiKeyProvider.cs
Normal file
48
src/isnd/Services/ApiKeyProvider.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using isnd.Data;
|
||||
using isnd.Data.ApiKeys;
|
||||
using isnd.Entities;
|
||||
using isnd.Interfaces;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace isnd;
|
||||
|
||||
|
||||
public class ApiKeyProvider : IApiKeyProvider
|
||||
{
|
||||
private readonly IsndSettings isndSettings;
|
||||
private readonly IDataProtector protector;
|
||||
private readonly ApplicationDbContext dbContext;
|
||||
|
||||
public ApiKeyProvider(
|
||||
ApplicationDbContext dbContext,
|
||||
IDataProtectionProvider dataProtectionProvider, IOptions<IsndSettings> isndSettingsOptions)
|
||||
{
|
||||
this.dbContext = dbContext;
|
||||
isndSettings = isndSettingsOptions.Value;
|
||||
protector = dataProtectionProvider.CreateProtector(isndSettings.ProtectionTitle);
|
||||
}
|
||||
|
||||
public async Task<ApiKey> CreateApiKeyAsync(CreateModel model)
|
||||
{
|
||||
var newKey = new ApiKey{
|
||||
UserId = model.UserId,
|
||||
CreationDate = DateTime.Now,
|
||||
Name = model.Name,
|
||||
ValidityPeriodInDays = model.ValidityPeriodInDays
|
||||
};
|
||||
|
||||
_ = dbContext.ApiKeys.Add(newKey);
|
||||
_ = await dbContext.SaveChangesAsync();
|
||||
return newKey;
|
||||
}
|
||||
|
||||
public IQueryable<ApiKey> GetUserKeys(string identityName)
|
||||
{
|
||||
return dbContext.ApiKeys.Include(k => k.User).Where(k => k.User.UserName == identityName);
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ using System;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
|
||||
namespace isnd
|
||||
{
|
||||
@ -76,9 +77,9 @@ namespace isnd
|
||||
.AddTransient<IMailer, EmailSender>()
|
||||
.AddTransient<IEmailSender, EmailSender>()
|
||||
.AddTransient<IPackageManager, PackageManager>()
|
||||
.AddTransient<IApiKeyProvider, ApiKeyProvider>()
|
||||
.AddSingleton<IAuthorizationHandler, ValidApiKeyRequirementHandler>();
|
||||
|
||||
|
||||
services.AddAuthentication("Bearer")
|
||||
.AddJwtBearer("Bearer", options =>
|
||||
{
|
||||
|
Reference in New Issue
Block a user