Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Nitro/CommandLine/src/CommandLine/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

<_NitroIdentityClientId>$(NitroIdentityClientId)</_NitroIdentityClientId>
<_NitroIdentityScopes>$(NitroIdentityScopes)</_NitroIdentityScopes>
<_NitroApiClientId>$(NitroApiClientId)</_NitroApiClientId>
</PropertyGroup>

<MakeDir Directories="$(_GenDir)" />
Expand All @@ -23,6 +24,7 @@ namespace $(_SecretsNamespace)
{
internal const string NitroIdentityClientId = &quot;$(_NitroIdentityClientId)&quot;;
internal const string NitroIdentityScopes = &quot;$(_NitroIdentityScopes)&quot;;
internal const string NitroApiClientId = &quot;$(_NitroApiClientId)&quot;;
}
}
))" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public Uri Url

public INitroClientAuthorization? Authorization { get; private set; }

public string? ClientId => BuildSecrets.NitroApiClientId;

public void Configure(string? apiUrl, INitroClientAuthorization? authorization)
{
if (string.IsNullOrWhiteSpace(apiUrl))
Expand Down
58 changes: 58 additions & 0 deletions src/Nitro/CommandLine/test/CommandLine.Tests/GlobalOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,57 @@ public async Task ExecuteAsync_Should_PreferApiKey_Over_SessionToken()
Assert.False(client.DefaultRequestHeaders.Contains("Authorization"));
}

[Fact]
public async Task ExecuteAsync_Should_ConfigureApiKeyAuth_When_EnvApiKeySet()
{
// arrange
var envProvider = CreateEnvironmentProvider(apiKey: "env-key");

// act
await using var provider = await BuildAndExecuteAsync([], environmentVariables: envProvider);
using var client = CreateApiClient(provider);

// assert
var apiKeyHeader = Assert.Single(client.DefaultRequestHeaders.GetValues("CCC-api-key"));
Assert.Equal("env-key", apiKeyHeader);
Assert.False(client.DefaultRequestHeaders.Contains("Authorization"));
}

[Fact]
public async Task ExecuteAsync_Should_PreferEnvApiKey_Over_SessionToken()
{
// arrange
var session = CreateSessionWithTokens(accessToken: "session-token");
var envProvider = CreateEnvironmentProvider(apiKey: "env-key");

// act
await using var provider = await BuildAndExecuteAsync(
[], session, environmentVariables: envProvider);
using var client = CreateApiClient(provider);

// assert
var apiKeyHeader = Assert.Single(client.DefaultRequestHeaders.GetValues("CCC-api-key"));
Assert.Equal("env-key", apiKeyHeader);
Assert.False(client.DefaultRequestHeaders.Contains("Authorization"));
}

[Fact]
public async Task ExecuteAsync_Should_PreferExplicitApiKey_Over_EnvApiKey()
{
// arrange
var envProvider = CreateEnvironmentProvider(apiKey: "env-key");

// act
await using var provider = await BuildAndExecuteAsync(
["--api-key", "cli-key"], environmentVariables: envProvider);
using var client = CreateApiClient(provider);

// assert
var apiKeyHeader = Assert.Single(client.DefaultRequestHeaders.GetValues("CCC-api-key"));
Assert.Equal("cli-key", apiKeyHeader);
Assert.False(client.DefaultRequestHeaders.Contains("Authorization"));
}

[Theory]
[InlineData("custom.host.com", "https://custom.host.com/graphql")]
[InlineData("https://custom.host.com", "https://custom.host.com/graphql")]
Expand Down Expand Up @@ -239,6 +290,13 @@ private static HttpClient CreateApiClient(ServiceProvider provider)
return factory.CreateClient(ApiClient.ClientName);
}

private static IEnvironmentVariableProvider CreateEnvironmentProvider(string? apiKey = null)
{
var mock = new Mock<IEnvironmentVariableProvider>();
mock.Setup(x => x.GetEnvironmentVariable("NITRO_API_KEY")).Returns(apiKey);
return mock.Object;
}

private static Session CreateSessionWithTokens(
string apiUrl = "api.chillicream.com",
string accessToken = "test-access-token")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ private static void ConfigureApiHttpClient(IServiceProvider sp, HttpClient clien
var provider = sp.GetRequiredService<INitroClientContextProvider>();
client.BaseAddress = provider.Url;

if (!string.IsNullOrWhiteSpace(provider.ClientId))
{
client.DefaultRequestHeaders.Remove(NitroClientHeaders.GraphQLClientId);
client.DefaultRequestHeaders.Add(NitroClientHeaders.GraphQLClientId, provider.ClientId);
}
Comment thread
tobias-tengler marked this conversation as resolved.

switch (provider.Authorization)
{
case NitroClientApiKeyAuthorization apiKey:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ public interface INitroClientContextProvider
Uri Url { get; }

INitroClientAuthorization? Authorization { get; }

string? ClientId { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace ChilliCream.Nitro.Client;

public static class NitroClientHeaders
{
public const string GraphQLClientId = "GraphQL-Client-Id";
public const string GraphQLClientVersion = "GraphQL-Client-Version";
public const string GraphQLPreflight = "GraphQL-Preflight";
public const string CccAgent = "ccc-agent";
Expand Down
Loading