119 lines
3.9 KiB
C#
119 lines
3.9 KiB
C#
|
|
using System.Text;
|
||
|
|
using System.Text.Json.Nodes;
|
||
|
|
using w4c_workflows.Models.Credentials;
|
||
|
|
using w4c_workflows.Services.Credentials;
|
||
|
|
using Xunit;
|
||
|
|
|
||
|
|
namespace w4c_workflows.Tests;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// The injection strategy turns a resolved credential into request material:
|
||
|
|
/// Basic/Bearer authorization, a custom header, or a query parameter.
|
||
|
|
/// </summary>
|
||
|
|
public class CredentialInjectorTests
|
||
|
|
{
|
||
|
|
private static readonly CredentialTypeCatalog Catalog = new();
|
||
|
|
|
||
|
|
private static HttpRequestMessage Request() => new(HttpMethod.Get, "https://api.example.com/items");
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Basic_sets_the_authorization_header()
|
||
|
|
{
|
||
|
|
var request = Request();
|
||
|
|
var credential = new CredentialData("httpBasicAuth", new JsonObject
|
||
|
|
{
|
||
|
|
["username"] = "ada",
|
||
|
|
["password"] = "secret",
|
||
|
|
});
|
||
|
|
|
||
|
|
Assert.Null(CredentialInjector.Apply(credential, Catalog, request));
|
||
|
|
|
||
|
|
var expected = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes("ada:secret"));
|
||
|
|
Assert.Equal(expected, request.Headers.Authorization!.ToString());
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Bearer_sets_the_authorization_header_with_the_prefix()
|
||
|
|
{
|
||
|
|
var request = Request();
|
||
|
|
var credential = new CredentialData("httpBearerAuth", new JsonObject { ["token"] = "tok-123" });
|
||
|
|
|
||
|
|
Assert.Null(CredentialInjector.Apply(credential, Catalog, request));
|
||
|
|
Assert.Equal("Bearer tok-123", request.Headers.Authorization!.ToString());
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Header_adds_a_custom_request_header()
|
||
|
|
{
|
||
|
|
var request = Request();
|
||
|
|
var credential = new CredentialData("httpHeaderAuth", new JsonObject
|
||
|
|
{
|
||
|
|
["name"] = "X-API-Key",
|
||
|
|
["value"] = "abc",
|
||
|
|
});
|
||
|
|
|
||
|
|
Assert.Null(CredentialInjector.Apply(credential, Catalog, request));
|
||
|
|
Assert.Equal("abc", request.Headers.GetValues("X-API-Key").Single());
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Query_appends_a_parameter()
|
||
|
|
{
|
||
|
|
var request = Request();
|
||
|
|
var credential = new CredentialData("httpQueryAuth", new JsonObject
|
||
|
|
{
|
||
|
|
["name"] = "api_key",
|
||
|
|
["value"] = "abc",
|
||
|
|
});
|
||
|
|
|
||
|
|
Assert.Null(CredentialInjector.Apply(credential, Catalog, request));
|
||
|
|
Assert.Contains("api_key=abc", request.RequestUri!.Query);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void A_missing_required_field_is_reported()
|
||
|
|
{
|
||
|
|
var request = Request();
|
||
|
|
var credential = new CredentialData("httpBearerAuth", new JsonObject());
|
||
|
|
|
||
|
|
var error = CredentialInjector.Apply(credential, Catalog, request);
|
||
|
|
|
||
|
|
Assert.NotNull(error);
|
||
|
|
Assert.Contains("token", error);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void An_unknown_type_is_reported()
|
||
|
|
{
|
||
|
|
var request = Request();
|
||
|
|
var credential = new CredentialData("nope", new JsonObject());
|
||
|
|
|
||
|
|
Assert.Equal("unknown credential type 'nope'", CredentialInjector.Apply(credential, Catalog, request));
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void None_injection_leaves_the_request_untouched()
|
||
|
|
{
|
||
|
|
var request = Request();
|
||
|
|
var credential = new CredentialData("telegramApi", new JsonObject { ["token"] = "123:ABC" });
|
||
|
|
|
||
|
|
Assert.Null(CredentialInjector.Apply(credential, Catalog, request));
|
||
|
|
Assert.Equal("https://api.example.com/items", request.RequestUri!.ToString());
|
||
|
|
Assert.Null(request.Headers.Authorization);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Catalog_exposes_the_url_embedded_credential_types()
|
||
|
|
{
|
||
|
|
var telegram = Catalog.Get("telegramApi");
|
||
|
|
var discord = Catalog.Get("discordWebhook");
|
||
|
|
|
||
|
|
Assert.NotNull(telegram);
|
||
|
|
Assert.NotNull(discord);
|
||
|
|
Assert.Equal(CredentialInjectionKind.None, telegram!.Injection.Kind);
|
||
|
|
Assert.Equal(CredentialInjectionKind.None, discord!.Injection.Kind);
|
||
|
|
Assert.Contains(telegram.Fields, f => f.Name == "token");
|
||
|
|
Assert.Contains(discord.Fields, f => f.Name == "url");
|
||
|
|
}
|
||
|
|
}
|