allow again the push
This commit is contained in:
parent
38bb7e40ef
commit
a78847dbc9
5 changed files with 94 additions and 7 deletions
|
|
@ -18,6 +18,8 @@ namespace Isn
|
||||||
source = Program.Settings.Sources.First(s=>s.Value.Alias==source).Key;
|
source = Program.Settings.Sources.First(s=>s.Value.Alias==source).Key;
|
||||||
if (source==null) throw new InvalidOperationException("source is invalid");
|
if (source==null) throw new InvalidOperationException("source is invalid");
|
||||||
|
|
||||||
|
var resolvedApiKey = string.IsNullOrWhiteSpace(apikey) ? ResolveSourceApiKey(source) : apikey;
|
||||||
|
|
||||||
var resources = SourceHelpers.GetServerResources(source);
|
var resources = SourceHelpers.GetServerResources(source);
|
||||||
if (resources.Resources == null)
|
if (resources.Resources == null)
|
||||||
throw new InvalidOperationException("source gave no resource");
|
throw new InvalidOperationException("source gave no resource");
|
||||||
|
|
@ -38,7 +40,7 @@ namespace Isn
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Console.WriteLine("Connecting to "+ pubRes.Id);
|
Console.WriteLine("Connecting to "+ pubRes.Id);
|
||||||
return client.UploadFilesToServer(new Uri(pubRes.Id), fi, apikey);
|
return client.UploadFilesToServer(new Uri(pubRes.Id), fi, resolvedApiKey);
|
||||||
}
|
}
|
||||||
catch (HttpRequestException hrex)
|
catch (HttpRequestException hrex)
|
||||||
{
|
{
|
||||||
|
|
@ -64,5 +66,25 @@ namespace Isn
|
||||||
return report;
|
return report;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string ResolveSourceApiKey(string source)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(source))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Program.Settings.Sources.Values.Any(s => s.Alias == source))
|
||||||
|
{
|
||||||
|
source = Program.Settings.Sources.First(s => s.Value.Alias == source).Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Program.Settings.Sources.TryGetValue(source, out var sourceSettings))
|
||||||
|
{
|
||||||
|
return sourceSettings.GetClearApiKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ namespace isnd.Controllers
|
||||||
var files = new List<string>();
|
var files = new List<string>();
|
||||||
ViewData["files"] = files;
|
ViewData["files"] = files;
|
||||||
|
|
||||||
var clearkey = ApiKeyProtector.UnprotectWithFallback(protector, apiKey);
|
var clearkey = ApiKeyProtector.TryUnprotectKey(protector, apiKey);
|
||||||
var apikey = dbContext.ApiKeys.SingleOrDefault(k => k.Id == clearkey);
|
var apikey = dbContext.ApiKeys.SingleOrDefault(k => k.Id == clearkey);
|
||||||
if (apikey == null)
|
if (apikey == null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,56 @@ namespace isnd.Helpers
|
||||||
{
|
{
|
||||||
private const byte LegacyDelta = 145;
|
private const byte LegacyDelta = 145;
|
||||||
|
|
||||||
public static string UnprotectWithFallback(IDataProtector protector, string protectedValue)
|
public static string TryUnprotectKey(IDataProtector protector, string protectedValue)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(protectedValue))
|
if (string.IsNullOrWhiteSpace(protectedValue))
|
||||||
{
|
{
|
||||||
return protectedValue;
|
return protectedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TryUnprotect(protector, protectedValue, out var unprotected))
|
||||||
|
{
|
||||||
|
return unprotected;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryUnprotectLegacy(protectedValue, out unprotected))
|
||||||
|
{
|
||||||
|
return unprotected;
|
||||||
|
}
|
||||||
|
|
||||||
|
return protectedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryUnprotect(IDataProtector protector, string protectedValue, out string unprotected)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return protector.Unprotect(protectedValue);
|
unprotected = protector.Unprotect(protectedValue);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
catch (CryptographicException)
|
catch (CryptographicException)
|
||||||
{
|
{
|
||||||
return UnprotectLegacy(protectedValue);
|
unprotected = null;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
catch (FormatException)
|
catch (FormatException)
|
||||||
{
|
{
|
||||||
return UnprotectLegacy(protectedValue);
|
unprotected = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryUnprotectLegacy(string protectedValue, out string unprotected)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
unprotected = UnprotectLegacy(protectedValue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
unprotected = null;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ namespace Isn.tests
|
||||||
private readonly string configDirectory;
|
private readonly string configDirectory;
|
||||||
private readonly string originalConfigDirectory;
|
private readonly string originalConfigDirectory;
|
||||||
|
|
||||||
|
public string LastApiKeyHeader { get; private set; }
|
||||||
|
|
||||||
public LocalSourceFixture()
|
public LocalSourceFixture()
|
||||||
{
|
{
|
||||||
var port = GetFreePort();
|
var port = GetFreePort();
|
||||||
|
|
@ -47,6 +49,11 @@ namespace Isn.tests
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.Request.HttpMethod == "PUT")
|
||||||
|
{
|
||||||
|
LastApiKeyHeader = context.Request.Headers["X-NuGet-ApiKey"];
|
||||||
|
}
|
||||||
|
|
||||||
var indexJson = JsonConvert.SerializeObject(new ApiIndexViewModel(prefix + "index.json")
|
var indexJson = JsonConvert.SerializeObject(new ApiIndexViewModel(prefix + "index.json")
|
||||||
{
|
{
|
||||||
Version = "3.0.0",
|
Version = "3.0.0",
|
||||||
|
|
@ -206,6 +213,22 @@ namespace Isn.tests
|
||||||
Assert.Single(report);
|
Assert.Single(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PushUsesStoredApiKeyFromConfigWhenNoExplicitApiKeyIsProvided()
|
||||||
|
{
|
||||||
|
Program.LoadConfig();
|
||||||
|
var clearApiKey = "stored-api-key";
|
||||||
|
Program.Settings.Sources[fixture.SourceUrl].SetApiKey(clearApiKey);
|
||||||
|
Program.SaveConfig();
|
||||||
|
Program.LoadConfig();
|
||||||
|
|
||||||
|
var report = Program.PushPkg(new[] { Path.Combine(AppContext.BaseDirectory, "dummy.nupkg") });
|
||||||
|
|
||||||
|
Assert.NotNull(report);
|
||||||
|
Assert.Single(report);
|
||||||
|
Assert.Equal(clearApiKey, fixture.LastApiKeyHeader);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetServerResourcesUsingHttpClientAsyncTest()
|
public void GetServerResourcesUsingHttpClientAsyncTest()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -58,11 +58,21 @@ namespace isnd.host.tests
|
||||||
const string clearValue = "legacy-api-key";
|
const string clearValue = "legacy-api-key";
|
||||||
var legacyProtectedValue = new Isn.DefaultDataProtector().Protect(clearValue);
|
var legacyProtectedValue = new Isn.DefaultDataProtector().Protect(clearValue);
|
||||||
|
|
||||||
var unprotected = ApiKeyProtector.UnprotectWithFallback(new ThrowingProtector(), legacyProtectedValue);
|
var unprotected = ApiKeyProtector.TryUnprotectKey(new ThrowingProtector(), legacyProtectedValue);
|
||||||
|
|
||||||
Assert.Equal(clearValue, unprotected);
|
Assert.Equal(clearValue, unprotected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ApiKeyProtectorReturnsRawValueWhenInputIsNotProtected()
|
||||||
|
{
|
||||||
|
const string rawApiKey = "CfDJ8AstXUEkxpJBrmoENwy__WNPxqcOwAuxyYgiU3Mebns5yxAT3VrC5vTuWTRSGZBFB7IGUyFkUYsp2nhRy64NqeUzLgOwEcU4FPOf-yaAtPeTMeStRd60bRh2ZYyQkQ3hrhW-lwpCLwYtNOnOyX2jayuzByF-4QfHIEhg6lbWenzf";
|
||||||
|
|
||||||
|
var result = ApiKeyProtector.TryUnprotectKey(new ThrowingProtector(), rawApiKey);
|
||||||
|
|
||||||
|
Assert.Equal(rawApiKey, result);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
void TestDropUser()
|
void TestDropUser()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue