diff --git a/src/PSInfisicalAPI.Tests/AuthProviderTests.cs b/src/PSInfisicalAPI.Tests/AuthProviderTests.cs new file mode 100644 index 0000000..51c2b13 --- /dev/null +++ b/src/PSInfisicalAPI.Tests/AuthProviderTests.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json.Linq; +using PSInfisicalAPI.Authentication; +using PSInfisicalAPI.Errors; +using PSInfisicalAPI.Http; +using PSInfisicalAPI.Security; +using Xunit; + +namespace PSInfisicalAPI.Tests +{ + public class AuthProviderTests + { + private sealed class CapturingHttpClient : IInfisicalHttpClient + { + public InfisicalHttpRequest CapturedRequest { get; private set; } + public string ResponseBody { get; set; } = "{\"accessToken\":\"abc.def.ghi\",\"expiresIn\":3600,\"tokenType\":\"Bearer\"}"; + + public InfisicalHttpResponse Send(InfisicalHttpRequest request) + { + CapturedRequest = request; + return new InfisicalHttpResponse + { + StatusCode = 200, + Body = ResponseBody, + Headers = new Dictionary() + }; + } + } + + private static InfisicalAuthenticationRequest BaseRequest() + { + return new InfisicalAuthenticationRequest + { + BaseUri = new Uri("https://example.invalid"), + ApiVersion = "v1" + }; + } + + [Fact] + public void JwtAuthProvider_Posts_IdentityId_And_Jwt() + { + CapturingHttpClient http = new CapturingHttpClient(); + InfisicalAuthenticationRequest request = BaseRequest(); + request.IdentityId = "identity-1"; + request.Jwt = SecureStringUtility.ToReadOnlySecureString("token.value"); + + InfisicalAuthenticationResult result = new JwtAuthProvider().Authenticate(request, http, null); + + Assert.NotNull(result); + Assert.NotNull(http.CapturedRequest); + Assert.Equal("POST", http.CapturedRequest.Method); + Assert.EndsWith("/api/v1/auth/jwt-auth/login", http.CapturedRequest.Uri.AbsolutePath); + JObject body = JObject.Parse(http.CapturedRequest.Body); + Assert.Equal("identity-1", (string)body["identityId"]); + Assert.Equal("token.value", (string)body["jwt"]); + } + + [Fact] + public void OidcAuthProvider_Posts_IdentityId_And_Jwt_To_Oidc_Endpoint() + { + CapturingHttpClient http = new CapturingHttpClient(); + InfisicalAuthenticationRequest request = BaseRequest(); + request.IdentityId = "identity-2"; + request.Jwt = SecureStringUtility.ToReadOnlySecureString("oidc.token"); + + new OidcAuthProvider().Authenticate(request, http, null); + + Assert.EndsWith("/api/v1/auth/oidc-auth/login", http.CapturedRequest.Uri.AbsolutePath); + JObject body = JObject.Parse(http.CapturedRequest.Body); + Assert.Equal("identity-2", (string)body["identityId"]); + Assert.Equal("oidc.token", (string)body["jwt"]); + } + + [Fact] + public void LdapAuthProvider_Posts_Username_And_Password_To_Ldap_Endpoint() + { + CapturingHttpClient http = new CapturingHttpClient(); + InfisicalAuthenticationRequest request = BaseRequest(); + request.Username = "svc.account"; + request.Password = SecureStringUtility.ToReadOnlySecureString("P@ssw0rd!"); + + new LdapAuthProvider().Authenticate(request, http, null); + + Assert.EndsWith("/api/v1/auth/ldap-auth/login", http.CapturedRequest.Uri.AbsolutePath); + JObject body = JObject.Parse(http.CapturedRequest.Body); + Assert.Equal("svc.account", (string)body["username"]); + Assert.Equal("P@ssw0rd!", (string)body["password"]); + Assert.False(body.ContainsKey("identityId")); + } + + [Fact] + public void LdapAuthProvider_Includes_IdentityId_When_Supplied() + { + CapturingHttpClient http = new CapturingHttpClient(); + InfisicalAuthenticationRequest request = BaseRequest(); + request.Username = "u"; + request.Password = SecureStringUtility.ToReadOnlySecureString("p"); + request.IdentityId = "id-ldap"; + + new LdapAuthProvider().Authenticate(request, http, null); + + JObject body = JObject.Parse(http.CapturedRequest.Body); + Assert.Equal("id-ldap", (string)body["identityId"]); + } + + [Fact] + public void AzureAuthProvider_Posts_IdentityId_And_Jwt_To_Azure_Endpoint() + { + CapturingHttpClient http = new CapturingHttpClient(); + InfisicalAuthenticationRequest request = BaseRequest(); + request.IdentityId = "identity-az"; + request.Jwt = SecureStringUtility.ToReadOnlySecureString("az.token"); + + new AzureAuthProvider().Authenticate(request, http, null); + + Assert.EndsWith("/api/v1/auth/azure-auth/login", http.CapturedRequest.Uri.AbsolutePath); + JObject body = JObject.Parse(http.CapturedRequest.Body); + Assert.Equal("identity-az", (string)body["identityId"]); + Assert.Equal("az.token", (string)body["jwt"]); + } + + [Fact] + public void GcpIamAuthProvider_Posts_IdentityId_And_Jwt_To_Gcp_Endpoint() + { + CapturingHttpClient http = new CapturingHttpClient(); + InfisicalAuthenticationRequest request = BaseRequest(); + request.IdentityId = "identity-gcp"; + request.Jwt = SecureStringUtility.ToReadOnlySecureString("gcp.token"); + + new GcpIamAuthProvider().Authenticate(request, http, null); + + Assert.EndsWith("/api/v1/auth/gcp-auth/login", http.CapturedRequest.Uri.AbsolutePath); + JObject body = JObject.Parse(http.CapturedRequest.Body); + Assert.Equal("identity-gcp", (string)body["identityId"]); + Assert.Equal("gcp.token", (string)body["jwt"]); + } + + [Fact] + public void JwtAuthProvider_Throws_When_IdentityId_Missing() + { + InfisicalAuthenticationRequest request = BaseRequest(); + request.Jwt = SecureStringUtility.ToReadOnlySecureString("x"); + Assert.Throws(() => + new JwtAuthProvider().Authenticate(request, new CapturingHttpClient(), null)); + } + + [Fact] + public void LdapAuthProvider_Throws_When_Password_Missing() + { + InfisicalAuthenticationRequest request = BaseRequest(); + request.Username = "u"; + Assert.Throws(() => + new LdapAuthProvider().Authenticate(request, new CapturingHttpClient(), null)); + } + } +} diff --git a/src/PSInfisicalAPI.Tests/EndpointRegistryTests.cs b/src/PSInfisicalAPI.Tests/EndpointRegistryTests.cs index 1edada8..adeccf3 100644 --- a/src/PSInfisicalAPI.Tests/EndpointRegistryTests.cs +++ b/src/PSInfisicalAPI.Tests/EndpointRegistryTests.cs @@ -69,8 +69,6 @@ namespace PSInfisicalAPI.Tests [InlineData(InfisicalEndpointNames.JwtAuthLogin, "POST", "/api/v1/auth/jwt-auth/login")] [InlineData(InfisicalEndpointNames.OidcAuthLogin, "POST", "/api/v1/auth/oidc-auth/login")] [InlineData(InfisicalEndpointNames.LdapAuthLogin, "POST", "/api/v1/auth/ldap-auth/login")] - [InlineData(InfisicalEndpointNames.KubernetesAuthLogin, "POST", "/api/v1/auth/kubernetes-auth/login")] - [InlineData(InfisicalEndpointNames.AwsAuthLogin, "POST", "/api/v1/auth/aws-auth/login")] [InlineData(InfisicalEndpointNames.AzureAuthLogin, "POST", "/api/v1/auth/azure-auth/login")] [InlineData(InfisicalEndpointNames.GcpIamAuthLogin, "POST", "/api/v1/auth/gcp-auth/login")] public void Registered_Endpoints_Have_Expected_Shape(string name, string method, string template) diff --git a/src/PSInfisicalAPI/Authentication/AzureAuthProvider.cs b/src/PSInfisicalAPI/Authentication/AzureAuthProvider.cs new file mode 100644 index 0000000..9d9b53a --- /dev/null +++ b/src/PSInfisicalAPI/Authentication/AzureAuthProvider.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using PSInfisicalAPI.Endpoints; +using PSInfisicalAPI.Errors; +using PSInfisicalAPI.Http; +using PSInfisicalAPI.Logging; +using PSInfisicalAPI.Security; + +namespace PSInfisicalAPI.Authentication +{ + public sealed class AzureAuthProvider : IInfisicalAuthProvider + { + private const string Component = "AzureAuthProvider"; + + public string Name { get { return "AzureAuth"; } } + + public InfisicalAuthenticationResult Authenticate(InfisicalAuthenticationRequest request, IInfisicalHttpClient httpClient, IInfisicalLogger logger) + { + if (request == null || string.IsNullOrEmpty(request.IdentityId)) + { + throw new InfisicalAuthenticationException("IdentityId is required for Azure Auth."); + } + + if (request.Jwt == null || request.Jwt.Length == 0) + { + throw new InfisicalAuthenticationException("Jwt is required for Azure Auth."); + } + + return IdentityLoginExecutor.Execute(InfisicalEndpointNames.AzureAuthLogin, Component, request, httpClient, logger, serializer => + { + return SecureStringUtility.UsePlainText(request.Jwt, plainJwt => + { + Dictionary bodyObject = new Dictionary + { + { "identityId", request.IdentityId }, + { "jwt", plainJwt ?? string.Empty } + }; + + return serializer.Serialize(bodyObject); + }); + }); + } + } +} diff --git a/src/PSInfisicalAPI/Authentication/GcpIamAuthProvider.cs b/src/PSInfisicalAPI/Authentication/GcpIamAuthProvider.cs new file mode 100644 index 0000000..3423ea6 --- /dev/null +++ b/src/PSInfisicalAPI/Authentication/GcpIamAuthProvider.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using PSInfisicalAPI.Endpoints; +using PSInfisicalAPI.Errors; +using PSInfisicalAPI.Http; +using PSInfisicalAPI.Logging; +using PSInfisicalAPI.Security; + +namespace PSInfisicalAPI.Authentication +{ + public sealed class GcpIamAuthProvider : IInfisicalAuthProvider + { + private const string Component = "GcpIamAuthProvider"; + + public string Name { get { return "GcpIamAuth"; } } + + public InfisicalAuthenticationResult Authenticate(InfisicalAuthenticationRequest request, IInfisicalHttpClient httpClient, IInfisicalLogger logger) + { + if (request == null || string.IsNullOrEmpty(request.IdentityId)) + { + throw new InfisicalAuthenticationException("IdentityId is required for GCP IAM Auth."); + } + + if (request.Jwt == null || request.Jwt.Length == 0) + { + throw new InfisicalAuthenticationException("Jwt is required for GCP IAM Auth."); + } + + return IdentityLoginExecutor.Execute(InfisicalEndpointNames.GcpIamAuthLogin, Component, request, httpClient, logger, serializer => + { + return SecureStringUtility.UsePlainText(request.Jwt, plainJwt => + { + Dictionary bodyObject = new Dictionary + { + { "identityId", request.IdentityId }, + { "jwt", plainJwt ?? string.Empty } + }; + + return serializer.Serialize(bodyObject); + }); + }); + } + } +} diff --git a/src/PSInfisicalAPI/Authentication/IdentityLoginExecutor.cs b/src/PSInfisicalAPI/Authentication/IdentityLoginExecutor.cs new file mode 100644 index 0000000..1e3baf0 --- /dev/null +++ b/src/PSInfisicalAPI/Authentication/IdentityLoginExecutor.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Security; +using PSInfisicalAPI.Endpoints; +using PSInfisicalAPI.Errors; +using PSInfisicalAPI.Http; +using PSInfisicalAPI.Logging; +using PSInfisicalAPI.Security; +using PSInfisicalAPI.Serialization; + +namespace PSInfisicalAPI.Authentication +{ + internal static class IdentityLoginExecutor + { + internal static InfisicalAuthenticationResult Execute( + string endpointName, + string component, + InfisicalAuthenticationRequest request, + IInfisicalHttpClient httpClient, + IInfisicalLogger logger, + Func bodyFactory) + { + if (request == null) { throw new ArgumentNullException(nameof(request)); } + if (httpClient == null) { throw new ArgumentNullException(nameof(httpClient)); } + if (bodyFactory == null) { throw new ArgumentNullException(nameof(bodyFactory)); } + + IInfisicalLogger log = logger ?? NullInfisicalLogger.Instance; + log.Information(component, "Attempting to authenticate to Infisical. Please Wait..."); + + InfisicalEndpointDefinition definition = InfisicalEndpointRegistry.Get(endpointName); + Uri uri = InfisicalUriBuilder.Build(request.BaseUri, definition, null, null); + JsonInfisicalSerializer serializer = new JsonInfisicalSerializer(); + string body = bodyFactory(serializer); + + InfisicalHttpRequest httpRequest = new InfisicalHttpRequest + { + OperationName = "Authenticate", + EndpointName = definition.Name, + Method = definition.Method, + Uri = uri, + Body = body, + ContentType = "application/json", + ContainsSecretMaterialInRequest = definition.ContainsSecretMaterialInRequest, + ContainsSecretMaterialInResponse = definition.ContainsSecretMaterialInResponse, + Headers = new Dictionary { { "Accept", "application/json" } } + }; + + InfisicalHttpResponse response = httpClient.Send(httpRequest); + + try + { + if (response.StatusCode < 200 || response.StatusCode >= 300) + { + log.Error(component, "Infisical authentication failed."); + throw new InfisicalAuthenticationException(string.Concat(component, " login returned status ", response.StatusCode.ToString(CultureInfo.InvariantCulture), ".")); + } + + IdentityLoginResponse parsed = serializer.Deserialize(response.Body); + if (parsed == null || string.IsNullOrEmpty(parsed.AccessToken)) + { + throw new InfisicalAuthenticationException(string.Concat(component, " login response did not contain an access token.")); + } + + SecureString accessToken = SecureStringUtility.ToReadOnlySecureString(parsed.AccessToken); + + DateTimeOffset? expiresAt = null; + if (parsed.ExpiresIn > 0) + { + expiresAt = DateTimeOffset.UtcNow.AddSeconds(parsed.ExpiresIn); + } + + parsed.AccessToken = null; + + log.Information(component, "Infisical authentication was successful."); + return new InfisicalAuthenticationResult + { + AccessToken = accessToken, + TokenType = string.IsNullOrEmpty(parsed.TokenType) ? "Bearer" : parsed.TokenType, + ExpiresAtUtc = expiresAt + }; + } + finally + { + response.Clear(); + } + } + + private sealed class IdentityLoginResponse + { + [Newtonsoft.Json.JsonProperty("accessToken")] + public string AccessToken { get; set; } + + [Newtonsoft.Json.JsonProperty("expiresIn")] + public int ExpiresIn { get; set; } + + [Newtonsoft.Json.JsonProperty("tokenType")] + public string TokenType { get; set; } + } + } +} diff --git a/src/PSInfisicalAPI/Authentication/InfisicalAuthenticationRequest.cs b/src/PSInfisicalAPI/Authentication/InfisicalAuthenticationRequest.cs index f2c5be8..6fecb09 100644 --- a/src/PSInfisicalAPI/Authentication/InfisicalAuthenticationRequest.cs +++ b/src/PSInfisicalAPI/Authentication/InfisicalAuthenticationRequest.cs @@ -10,5 +10,10 @@ namespace PSInfisicalAPI.Authentication public string ClientId { get; set; } public SecureString ClientSecret { get; set; } public SecureString PreSuppliedAccessToken { get; set; } + + public string IdentityId { get; set; } + public SecureString Jwt { get; set; } + public string Username { get; set; } + public SecureString Password { get; set; } } } diff --git a/src/PSInfisicalAPI/Authentication/JwtAuthProvider.cs b/src/PSInfisicalAPI/Authentication/JwtAuthProvider.cs new file mode 100644 index 0000000..e9ee4e8 --- /dev/null +++ b/src/PSInfisicalAPI/Authentication/JwtAuthProvider.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using PSInfisicalAPI.Endpoints; +using PSInfisicalAPI.Errors; +using PSInfisicalAPI.Http; +using PSInfisicalAPI.Logging; +using PSInfisicalAPI.Security; + +namespace PSInfisicalAPI.Authentication +{ + public sealed class JwtAuthProvider : IInfisicalAuthProvider + { + private const string Component = "JwtAuthProvider"; + + public string Name { get { return "JwtAuth"; } } + + public InfisicalAuthenticationResult Authenticate(InfisicalAuthenticationRequest request, IInfisicalHttpClient httpClient, IInfisicalLogger logger) + { + if (request == null || string.IsNullOrEmpty(request.IdentityId)) + { + throw new InfisicalAuthenticationException("IdentityId is required for JWT Auth."); + } + + if (request.Jwt == null || request.Jwt.Length == 0) + { + throw new InfisicalAuthenticationException("Jwt is required for JWT Auth."); + } + + return IdentityLoginExecutor.Execute(InfisicalEndpointNames.JwtAuthLogin, Component, request, httpClient, logger, serializer => + { + return SecureStringUtility.UsePlainText(request.Jwt, plainJwt => + { + Dictionary bodyObject = new Dictionary + { + { "identityId", request.IdentityId }, + { "jwt", plainJwt ?? string.Empty } + }; + + return serializer.Serialize(bodyObject); + }); + }); + } + } +} diff --git a/src/PSInfisicalAPI/Authentication/LdapAuthProvider.cs b/src/PSInfisicalAPI/Authentication/LdapAuthProvider.cs new file mode 100644 index 0000000..d670dd3 --- /dev/null +++ b/src/PSInfisicalAPI/Authentication/LdapAuthProvider.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using PSInfisicalAPI.Endpoints; +using PSInfisicalAPI.Errors; +using PSInfisicalAPI.Http; +using PSInfisicalAPI.Logging; +using PSInfisicalAPI.Security; + +namespace PSInfisicalAPI.Authentication +{ + public sealed class LdapAuthProvider : IInfisicalAuthProvider + { + private const string Component = "LdapAuthProvider"; + + public string Name { get { return "LdapAuth"; } } + + public InfisicalAuthenticationResult Authenticate(InfisicalAuthenticationRequest request, IInfisicalHttpClient httpClient, IInfisicalLogger logger) + { + if (request == null || string.IsNullOrEmpty(request.Username)) + { + throw new InfisicalAuthenticationException("Username is required for LDAP Auth."); + } + + if (request.Password == null || request.Password.Length == 0) + { + throw new InfisicalAuthenticationException("Password is required for LDAP Auth."); + } + + return IdentityLoginExecutor.Execute(InfisicalEndpointNames.LdapAuthLogin, Component, request, httpClient, logger, serializer => + { + return SecureStringUtility.UsePlainText(request.Password, plainPassword => + { + Dictionary bodyObject = new Dictionary + { + { "username", request.Username }, + { "password", plainPassword ?? string.Empty } + }; + + if (!string.IsNullOrEmpty(request.IdentityId)) + { + bodyObject["identityId"] = request.IdentityId; + } + + return serializer.Serialize(bodyObject); + }); + }); + } + } +} diff --git a/src/PSInfisicalAPI/Authentication/OidcAuthProvider.cs b/src/PSInfisicalAPI/Authentication/OidcAuthProvider.cs new file mode 100644 index 0000000..5361010 --- /dev/null +++ b/src/PSInfisicalAPI/Authentication/OidcAuthProvider.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using PSInfisicalAPI.Endpoints; +using PSInfisicalAPI.Errors; +using PSInfisicalAPI.Http; +using PSInfisicalAPI.Logging; +using PSInfisicalAPI.Security; + +namespace PSInfisicalAPI.Authentication +{ + public sealed class OidcAuthProvider : IInfisicalAuthProvider + { + private const string Component = "OidcAuthProvider"; + + public string Name { get { return "OidcAuth"; } } + + public InfisicalAuthenticationResult Authenticate(InfisicalAuthenticationRequest request, IInfisicalHttpClient httpClient, IInfisicalLogger logger) + { + if (request == null || string.IsNullOrEmpty(request.IdentityId)) + { + throw new InfisicalAuthenticationException("IdentityId is required for OIDC Auth."); + } + + if (request.Jwt == null || request.Jwt.Length == 0) + { + throw new InfisicalAuthenticationException("Jwt is required for OIDC Auth."); + } + + return IdentityLoginExecutor.Execute(InfisicalEndpointNames.OidcAuthLogin, Component, request, httpClient, logger, serializer => + { + return SecureStringUtility.UsePlainText(request.Jwt, plainJwt => + { + Dictionary bodyObject = new Dictionary + { + { "identityId", request.IdentityId }, + { "jwt", plainJwt ?? string.Empty } + }; + + return serializer.Serialize(bodyObject); + }); + }); + } + } +} diff --git a/src/PSInfisicalAPI/Cmdlets/ConnectInfisicalCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/ConnectInfisicalCmdlet.cs index f5e6bdd..08834df 100644 --- a/src/PSInfisicalAPI/Cmdlets/ConnectInfisicalCmdlet.cs +++ b/src/PSInfisicalAPI/Cmdlets/ConnectInfisicalCmdlet.cs @@ -15,6 +15,11 @@ namespace PSInfisicalAPI.Cmdlets { private const string ParameterSetUniversalAuth = "UniversalAuth"; private const string ParameterSetToken = "Token"; + private const string ParameterSetJwt = "JwtAuth"; + private const string ParameterSetOidc = "OidcAuth"; + private const string ParameterSetLdap = "LdapAuth"; + private const string ParameterSetAzure = "AzureAuth"; + private const string ParameterSetGcpIam = "GcpIamAuth"; private const string Component = "ConnectInfisicalCmdlet"; [Parameter] @@ -38,6 +43,25 @@ namespace PSInfisicalAPI.Cmdlets [Parameter(ParameterSetName = ParameterSetToken)] public SecureString AccessToken { get; set; } + [Parameter(Mandatory = true, ParameterSetName = ParameterSetJwt)] + [Parameter(Mandatory = true, ParameterSetName = ParameterSetOidc)] + [Parameter(Mandatory = true, ParameterSetName = ParameterSetAzure)] + [Parameter(Mandatory = true, ParameterSetName = ParameterSetGcpIam)] + [Parameter(ParameterSetName = ParameterSetLdap)] + public string IdentityId { get; set; } + + [Parameter(Mandatory = true, ParameterSetName = ParameterSetJwt)] + [Parameter(Mandatory = true, ParameterSetName = ParameterSetOidc)] + [Parameter(Mandatory = true, ParameterSetName = ParameterSetAzure)] + [Parameter(Mandatory = true, ParameterSetName = ParameterSetGcpIam)] + public SecureString Jwt { get; set; } + + [Parameter(Mandatory = true, ParameterSetName = ParameterSetLdap)] + public string Username { get; set; } + + [Parameter(Mandatory = true, ParameterSetName = ParameterSetLdap)] + public SecureString Password { get; set; } + [Parameter] public string SecretPath { get; set; } = "/"; @@ -58,28 +82,91 @@ namespace PSInfisicalAPI.Cmdlets InfisicalAuthenticationRequest request; InfisicalAuthType authType; - if (string.Equals(ParameterSetName, ParameterSetToken, StringComparison.Ordinal)) + switch (ParameterSetName) { - provider = new TokenAuthProvider(); - authType = InfisicalAuthType.Token; - request = new InfisicalAuthenticationRequest - { - BaseUri = BaseUri, - ApiVersion = ApiVersion, - PreSuppliedAccessToken = AccessToken - }; - } - else - { - provider = new UniversalAuthProvider(); - authType = InfisicalAuthType.UniversalAuth; - request = new InfisicalAuthenticationRequest - { - BaseUri = BaseUri, - ApiVersion = ApiVersion, - ClientId = ClientId, - ClientSecret = ClientSecret - }; + case ParameterSetToken: + provider = new TokenAuthProvider(); + authType = InfisicalAuthType.Token; + request = new InfisicalAuthenticationRequest + { + BaseUri = BaseUri, + ApiVersion = ApiVersion, + PreSuppliedAccessToken = AccessToken + }; + break; + + case ParameterSetJwt: + provider = new JwtAuthProvider(); + authType = InfisicalAuthType.Jwt; + request = new InfisicalAuthenticationRequest + { + BaseUri = BaseUri, + ApiVersion = ApiVersion, + IdentityId = IdentityId, + Jwt = Jwt + }; + break; + + case ParameterSetOidc: + provider = new OidcAuthProvider(); + authType = InfisicalAuthType.Oidc; + request = new InfisicalAuthenticationRequest + { + BaseUri = BaseUri, + ApiVersion = ApiVersion, + IdentityId = IdentityId, + Jwt = Jwt + }; + break; + + case ParameterSetLdap: + provider = new LdapAuthProvider(); + authType = InfisicalAuthType.Ldap; + request = new InfisicalAuthenticationRequest + { + BaseUri = BaseUri, + ApiVersion = ApiVersion, + IdentityId = IdentityId, + Username = Username, + Password = Password + }; + break; + + case ParameterSetAzure: + provider = new AzureAuthProvider(); + authType = InfisicalAuthType.Azure; + request = new InfisicalAuthenticationRequest + { + BaseUri = BaseUri, + ApiVersion = ApiVersion, + IdentityId = IdentityId, + Jwt = Jwt + }; + break; + + case ParameterSetGcpIam: + provider = new GcpIamAuthProvider(); + authType = InfisicalAuthType.GcpIam; + request = new InfisicalAuthenticationRequest + { + BaseUri = BaseUri, + ApiVersion = ApiVersion, + IdentityId = IdentityId, + Jwt = Jwt + }; + break; + + default: + provider = new UniversalAuthProvider(); + authType = InfisicalAuthType.UniversalAuth; + request = new InfisicalAuthenticationRequest + { + BaseUri = BaseUri, + ApiVersion = ApiVersion, + ClientId = ClientId, + ClientSecret = ClientSecret + }; + break; } InfisicalAuthenticationResult authResult = provider.Authenticate(request, HttpClient, Logger); @@ -123,6 +210,7 @@ namespace PSInfisicalAPI.Cmdlets private void ResolveMissingParametersFromEnvironment() { bool tokenSet = string.Equals(ParameterSetName, ParameterSetToken, StringComparison.Ordinal); + bool universalSet = string.Equals(ParameterSetName, ParameterSetUniversalAuth, StringComparison.Ordinal); bool needsScan = BaseUri == null || @@ -130,8 +218,8 @@ namespace PSInfisicalAPI.Cmdlets string.IsNullOrWhiteSpace(ProjectId) || string.IsNullOrWhiteSpace(Environment) || (tokenSet && (AccessToken == null || AccessToken.Length == 0)) || - (!tokenSet && string.IsNullOrWhiteSpace(ClientId)) || - (!tokenSet && (ClientSecret == null || ClientSecret.Length == 0)); + (universalSet && string.IsNullOrWhiteSpace(ClientId)) || + (universalSet && (ClientSecret == null || ClientSecret.Length == 0)); if (!needsScan) { @@ -161,7 +249,7 @@ namespace PSInfisicalAPI.Cmdlets { AccessToken = InfisicalEnvironmentResolver.ResolveSecureString("AccessToken", InfisicalEnvironmentResolver.AccessTokenPatterns, AccessToken, Logger); } - else + else if (universalSet) { ClientId = InfisicalEnvironmentResolver.ResolveString("ClientId", InfisicalEnvironmentResolver.ClientIdPatterns, ClientId, Logger); ClientSecret = InfisicalEnvironmentResolver.ResolveSecureString("ClientSecret", InfisicalEnvironmentResolver.ClientSecretPatterns, ClientSecret, Logger); @@ -199,7 +287,7 @@ namespace PSInfisicalAPI.Cmdlets { if (AccessToken == null || AccessToken.Length == 0) { missing.Add("AccessToken"); } } - else + else if (string.Equals(ParameterSetName, ParameterSetUniversalAuth, StringComparison.Ordinal)) { if (string.IsNullOrWhiteSpace(ClientId)) { missing.Add("ClientId"); } if (ClientSecret == null || ClientSecret.Length == 0) { missing.Add("ClientSecret"); } diff --git a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs index 2d331ba..83a8d0e 100644 --- a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs +++ b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs @@ -7,8 +7,6 @@ namespace PSInfisicalAPI.Endpoints public const string JwtAuthLogin = "JwtAuthLogin"; public const string OidcAuthLogin = "OidcAuthLogin"; public const string LdapAuthLogin = "LdapAuthLogin"; - public const string KubernetesAuthLogin = "KubernetesAuthLogin"; - public const string AwsAuthLogin = "AwsAuthLogin"; public const string AzureAuthLogin = "AzureAuthLogin"; public const string GcpIamAuthLogin = "GcpIamAuthLogin"; diff --git a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs index 1ccf72a..0478a5c 100644 --- a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs +++ b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs @@ -92,30 +92,6 @@ namespace PSInfisicalAPI.Endpoints ContainsSecretMaterialInResponse = true }); - Add(map, new InfisicalEndpointDefinition - { - Name = InfisicalEndpointNames.KubernetesAuthLogin, - Resource = "Authentication", - Version = "v1", - Method = "POST", - Template = "/api/v1/auth/kubernetes-auth/login", - RequiresAuthorization = false, - ContainsSecretMaterialInRequest = true, - ContainsSecretMaterialInResponse = true - }); - - Add(map, new InfisicalEndpointDefinition - { - Name = InfisicalEndpointNames.AwsAuthLogin, - Resource = "Authentication", - Version = "v1", - Method = "POST", - Template = "/api/v1/auth/aws-auth/login", - RequiresAuthorization = false, - ContainsSecretMaterialInRequest = true, - ContainsSecretMaterialInResponse = true - }); - Add(map, new InfisicalEndpointDefinition { Name = InfisicalEndpointNames.AzureAuthLogin, diff --git a/src/PSInfisicalAPI/Models/InfisicalAuthType.cs b/src/PSInfisicalAPI/Models/InfisicalAuthType.cs index 10e8496..d0729f6 100644 --- a/src/PSInfisicalAPI/Models/InfisicalAuthType.cs +++ b/src/PSInfisicalAPI/Models/InfisicalAuthType.cs @@ -3,6 +3,11 @@ namespace PSInfisicalAPI.Models public enum InfisicalAuthType { UniversalAuth, - Token + Token, + Jwt, + Oidc, + Ldap, + Azure, + GcpIam } }