cffda99591
BREAKING CHANGES
- Connect-Infisical no longer accepts -ProjectId, -Environment, or -SecretPath.
- InfisicalConnection no longer carries ProjectId, Environment, or DefaultSecretPath.
- Every cmdlet that previously inherited those fields now requires -ProjectId
and/or -Environment as Mandatory=true. -SecretPath / -Path remain optional
and default to "/" at the client layer.
- INFISICAL_PROJECT_ID, INFISICAL_ENVIRONMENT, INFISICAL_SECRET_PATH env-var
scanning removed from Connect-Infisical.
- Resolve{ProjectId,Environment,SecretPath} helpers removed from
InfisicalCmdletBase. ResolveOrganizationId retained.
ADDED
- Get-InfisicalProject -Type <enum> filters the list by product surface
(secret-manager, cert-manager, kms, ssh, secret-scanning, pam, ai) with
IntelliSense via ValidateSet.
- Get-InfisicalProject -IncludeRoles switch maps to includeRoles=true/false
query parameter (always sent).
RATIONALE
- Implicit connection scoping caused 400 Bad Request when the active
connection's ProjectId belonged to a different product surface than the
cmdlet's target (e.g. secret-manager project id passed to /cert-manager/*).
- Explicit parameters make scope unambiguous and make scripts portable
across projects.
- The new -Type filter on Get-InfisicalProject lets callers discover the
correct project id for each subsequent CRUD invocation without needing
connection-level inheritance.
INTERNAL
- All client classes (Secrets / Folders / Environments / Tags / Projects /
Pki) now receive scoping as explicit arguments rather than reading the
InfisicalConnection object.
- Client-layer SecretPath / Path defaulting to "/" is preserved via
FirstNonEmpty(...).
- Help XML updated to remove all "session-pinned" / "active connection"
phrasing; OrderedDictionary splatting examples now include the mandatory
parameters.
- 216/216 unit tests passing.
98 lines
4.0 KiB
C#
98 lines
4.0 KiB
C#
using System.Text.RegularExpressions;
|
|
using PSInfisicalAPI.Authentication;
|
|
using Xunit;
|
|
|
|
namespace PSInfisicalAPI.Tests
|
|
{
|
|
public class InfisicalEnvironmentPatternTests
|
|
{
|
|
[Theory]
|
|
[InlineData("INFISICAL_API_URL")]
|
|
[InlineData("INFISICAL_BASE_URL")]
|
|
[InlineData("INFISICAL_BASE_URI")]
|
|
[InlineData("INFISICAL_HOST")]
|
|
[InlineData("CLOUDINIT_INFISICAL_APIURL")]
|
|
public void BaseUriPatterns_Match_Expected_Names(string name)
|
|
{
|
|
Assert.True(MatchesAny(name, InfisicalEnvironmentResolver.BaseUriPatterns), "Expected match for " + name);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("INFISICAL_ORG_ID")]
|
|
[InlineData("INFISICAL_ORGANIZATION_ID")]
|
|
[InlineData("CLOUDINIT_INFISICAL_ORGANIZATIONID")]
|
|
public void OrganizationIdPatterns_Match_Expected_Names(string name)
|
|
{
|
|
Assert.True(MatchesAny(name, InfisicalEnvironmentResolver.OrganizationIdPatterns), "Expected match for " + name);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("INFISICAL_CLIENT_ID")]
|
|
[InlineData("INFISICAL_UNIVERSAL_AUTH_CLIENT_ID")]
|
|
[InlineData("INFISICAL_MACHINE_IDENTITY_CLIENT_ID")]
|
|
[InlineData("CLOUDINIT_INFISICAL_CLIENTID")]
|
|
[InlineData("myapp_infisical_client_id")]
|
|
public void ClientIdPatterns_Match_Standard_And_Custom_Prefixed_Names(string name)
|
|
{
|
|
Assert.True(MatchesAny(name, InfisicalEnvironmentResolver.ClientIdPatterns), "Expected match for " + name);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("INFISICAL_CLIENT_SECRET")]
|
|
[InlineData("INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET")]
|
|
[InlineData("INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET")]
|
|
[InlineData("CLOUDINIT_INFISICAL_CLIENTSECRET")]
|
|
[InlineData("myapp_infisical_client_secret")]
|
|
public void ClientSecretPatterns_Match_Standard_And_Custom_Prefixed_Names(string name)
|
|
{
|
|
Assert.True(MatchesAny(name, InfisicalEnvironmentResolver.ClientSecretPatterns), "Expected match for " + name);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("INFISICAL_TOKEN")]
|
|
[InlineData("INFISICAL_ACCESS_TOKEN")]
|
|
[InlineData("INFISICAL_AUTH_TOKEN")]
|
|
[InlineData("CLOUDINIT_INFISICAL_TOKEN")]
|
|
public void AccessTokenPatterns_Match_Expected_Names(string name)
|
|
{
|
|
Assert.True(MatchesAny(name, InfisicalEnvironmentResolver.AccessTokenPatterns), "Expected match for " + name);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("INFISICAL_SECRET_PATH")]
|
|
[InlineData("INFISICAL_DEFAULT_SECRET_PATH")]
|
|
[InlineData("CLOUDINIT_INFISICAL_SECRETPATH")]
|
|
public void ClientSecretPatterns_Do_Not_Match_SecretPath_Variables(string name)
|
|
{
|
|
Assert.False(MatchesAny(name, InfisicalEnvironmentResolver.ClientSecretPatterns), "ClientSecretPatterns should NOT match " + name);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("PATH")]
|
|
[InlineData("USERNAME")]
|
|
[InlineData("HOME")]
|
|
[InlineData("PROCESSOR_ARCHITECTURE")]
|
|
public void Patterns_Do_Not_Match_Unrelated_System_Variables(string name)
|
|
{
|
|
Assert.False(MatchesAny(name, InfisicalEnvironmentResolver.ClientIdPatterns));
|
|
Assert.False(MatchesAny(name, InfisicalEnvironmentResolver.ClientSecretPatterns));
|
|
Assert.False(MatchesAny(name, InfisicalEnvironmentResolver.AccessTokenPatterns));
|
|
Assert.False(MatchesAny(name, InfisicalEnvironmentResolver.BaseUriPatterns));
|
|
Assert.False(MatchesAny(name, InfisicalEnvironmentResolver.OrganizationIdPatterns));
|
|
Assert.False(MatchesAny(name, InfisicalEnvironmentResolver.ApiVersionPatterns));
|
|
}
|
|
|
|
private static bool MatchesAny(string input, Regex[] patterns)
|
|
{
|
|
for (int i = 0; i < patterns.Length; i++)
|
|
{
|
|
if (patterns[i].IsMatch(input))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|