Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public partial class ApiKeyCredential
{
public ApiKeyCredential(string key) { }
public void Deconstruct(out string key) { throw null; }
public static implicit operator System.ClientModel.ApiKeyCredential (string key) { throw null; }
public static System.ClientModel.ApiKeyCredential FromEnvironmentVariable(string variable) { throw null; }
public void Update(string key) { }
}
public abstract partial class AsyncCollectionResult<T> : System.ClientModel.ClientResult, System.Collections.Generic.IAsyncEnumerable<T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public partial class ApiKeyCredential
{
public ApiKeyCredential(string key) { }
public void Deconstruct(out string key) { throw null; }
public static implicit operator System.ClientModel.ApiKeyCredential (string key) { throw null; }
public static System.ClientModel.ApiKeyCredential FromEnvironmentVariable(string variable) { throw null; }
public void Update(string key) { }
}
public abstract partial class AsyncCollectionResult<T> : System.ClientModel.ClientResult, System.Collections.Generic.IAsyncEnumerable<T>
Expand Down
37 changes: 35 additions & 2 deletions sdk/core/System.ClientModel/src/Convenience/ApiKeyCredential.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System.ClientModel.Internal;
using System.Security;
using System.Threading;

namespace System.ClientModel;
Expand Down Expand Up @@ -66,6 +67,38 @@ public void Update(string key)
Volatile.Write(ref _key, key);
}

/// <summary> Converts a string to an <see cref="ApiKeyCredential"/>. </summary>
public static implicit operator ApiKeyCredential(string key) => new(key);
/// <summary>
/// Initializes a new instance of the <see cref="ApiKeyCredential"/> class
/// from the value stored in the specified environment variable.
/// </summary>
/// <param name="variable">
/// The name of the environment variable where the API key is stored.
/// </param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">
/// Thrown when the <paramref name="variable"/> is null.
/// </exception>
/// <exception cref="System.ArgumentException">
/// Thrown when the <paramref name="variable"/> is empty.
/// </exception>
/// <exception cref="ArgumentException">
/// Thrown when the environment variable is not found.
/// </exception>
/// <exception cref="SecurityException">
/// Thrown when the caller does not have the required permission to perform
/// this operation.
/// </exception>
public static ApiKeyCredential FromEnvironmentVariable(string variable)
{
Argument.AssertNotNullOrEmpty(variable, nameof(variable));

string? key = Environment.GetEnvironmentVariable(variable);

if (string.IsNullOrEmpty(key))
{
throw new ArgumentException($"Environment variable '{variable}' not found.");
}

return new ApiKeyCredential(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ public ApiKeyAuthenticationPolicyTests(bool isAsync) : base(isAsync)
}

[Test]
public void CanImplicitlyCastApiKeyCredential()
public void CreateFromEnvironmentVariable()
{
string keyValue = "test_key";
ApiKeyCredential credential1 = new(keyValue);
ApiKeyCredential credential2 = keyValue;
string variableName = "TEST_KEY_NAME";
string variableValue = "test_key_value";
Environment.SetEnvironmentVariable(variableName, variableValue);

credential1.Deconstruct(out string deconstructed1);
credential2.Deconstruct(out string deconstructed2);
ApiKeyCredential credential = ApiKeyCredential.FromEnvironmentVariable(variableName);
Assert.That(credential, Is.Not.Null);

Assert.AreEqual(deconstructed1, deconstructed2);
credential.Deconstruct(out string deconstructed);
Assert.That(deconstructed, Is.EqualTo(variableValue));
}

[Test]
Expand Down