Tests: roll forward to latest major .NET runtime #3
@@ -45,5 +45,39 @@ namespace PSInfisicalAPI.Tests
|
|||||||
{
|
{
|
||||||
Assert.Throws<InfisicalConfigurationException>(() => InfisicalEndpointRegistry.Get("NotARealEndpoint"));
|
Assert.Throws<InfisicalConfigurationException>(() => InfisicalEndpointRegistry.Get("NotARealEndpoint"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(InfisicalEndpointNames.CreateSecret, "POST", "/api/v3/secrets/raw/{secretName}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.UpdateSecret, "PATCH", "/api/v3/secrets/raw/{secretName}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.DeleteSecret, "DELETE", "/api/v3/secrets/raw/{secretName}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.ListProjects, "GET", "/api/v1/workspace")]
|
||||||
|
[InlineData(InfisicalEndpointNames.RetrieveProject, "GET", "/api/v1/workspace/{projectId}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.CreateProject, "POST", "/api/v2/workspace")]
|
||||||
|
[InlineData(InfisicalEndpointNames.UpdateProject, "PATCH", "/api/v1/workspace/{projectId}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.DeleteProject, "DELETE", "/api/v1/workspace/{projectId}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.CreateEnvironment, "POST", "/api/v1/workspace/{projectId}/environments")]
|
||||||
|
[InlineData(InfisicalEndpointNames.UpdateEnvironment, "PATCH", "/api/v1/workspace/{projectId}/environments/{environmentId}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.DeleteEnvironment, "DELETE", "/api/v1/workspace/{projectId}/environments/{environmentId}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.ListFolders, "GET", "/api/v1/folders")]
|
||||||
|
[InlineData(InfisicalEndpointNames.CreateFolder, "POST", "/api/v1/folders")]
|
||||||
|
[InlineData(InfisicalEndpointNames.UpdateFolder, "PATCH", "/api/v1/folders/{folderId}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.DeleteFolder, "DELETE", "/api/v1/folders/{folderId}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.ListTags, "GET", "/api/v1/workspace/{projectId}/tags")]
|
||||||
|
[InlineData(InfisicalEndpointNames.CreateTag, "POST", "/api/v1/workspace/{projectId}/tags")]
|
||||||
|
[InlineData(InfisicalEndpointNames.UpdateTag, "PATCH", "/api/v1/workspace/{projectId}/tags/{tagId}")]
|
||||||
|
[InlineData(InfisicalEndpointNames.DeleteTag, "DELETE", "/api/v1/workspace/{projectId}/tags/{tagId}")]
|
||||||
|
[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)
|
||||||
|
{
|
||||||
|
InfisicalEndpointDefinition definition = InfisicalEndpointRegistry.Get(name);
|
||||||
|
Assert.Equal(method, definition.Method);
|
||||||
|
Assert.Equal(template, definition.Template);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,43 @@ namespace PSInfisicalAPI.Endpoints
|
|||||||
public static class InfisicalEndpointNames
|
public static class InfisicalEndpointNames
|
||||||
{
|
{
|
||||||
public const string UniversalAuthLogin = "UniversalAuthLogin";
|
public const string UniversalAuthLogin = "UniversalAuthLogin";
|
||||||
|
public const string TokenAuthLogin = "TokenAuthLogin";
|
||||||
|
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";
|
||||||
|
|
||||||
public const string ListSecrets = "ListSecrets";
|
public const string ListSecrets = "ListSecrets";
|
||||||
public const string RetrieveSecret = "RetrieveSecret";
|
public const string RetrieveSecret = "RetrieveSecret";
|
||||||
|
public const string CreateSecret = "CreateSecret";
|
||||||
|
public const string UpdateSecret = "UpdateSecret";
|
||||||
|
public const string DeleteSecret = "DeleteSecret";
|
||||||
|
|
||||||
|
public const string ListProjects = "ListProjects";
|
||||||
|
public const string RetrieveProject = "RetrieveProject";
|
||||||
|
public const string CreateProject = "CreateProject";
|
||||||
|
public const string UpdateProject = "UpdateProject";
|
||||||
|
public const string DeleteProject = "DeleteProject";
|
||||||
|
|
||||||
|
public const string ListEnvironments = "ListEnvironments";
|
||||||
|
public const string RetrieveEnvironment = "RetrieveEnvironment";
|
||||||
|
public const string CreateEnvironment = "CreateEnvironment";
|
||||||
|
public const string UpdateEnvironment = "UpdateEnvironment";
|
||||||
|
public const string DeleteEnvironment = "DeleteEnvironment";
|
||||||
|
|
||||||
|
public const string ListFolders = "ListFolders";
|
||||||
|
public const string RetrieveFolder = "RetrieveFolder";
|
||||||
|
public const string CreateFolder = "CreateFolder";
|
||||||
|
public const string UpdateFolder = "UpdateFolder";
|
||||||
|
public const string DeleteFolder = "DeleteFolder";
|
||||||
|
|
||||||
|
public const string ListTags = "ListTags";
|
||||||
|
public const string RetrieveTag = "RetrieveTag";
|
||||||
|
public const string CreateTag = "CreateTag";
|
||||||
|
public const string UpdateTag = "UpdateTag";
|
||||||
|
public const string DeleteTag = "DeleteTag";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,83 +5,435 @@ namespace PSInfisicalAPI.Endpoints
|
|||||||
{
|
{
|
||||||
public static class InfisicalEndpointRegistry
|
public static class InfisicalEndpointRegistry
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, List<InfisicalEndpointDefinition>> Candidates =
|
private static readonly Dictionary<string, List<InfisicalEndpointDefinition>> Candidates;
|
||||||
new Dictionary<string, List<InfisicalEndpointDefinition>>
|
|
||||||
|
static InfisicalEndpointRegistry()
|
||||||
|
{
|
||||||
|
Candidates = new Dictionary<string, List<InfisicalEndpointDefinition>>();
|
||||||
|
RegisterAuthentication(Candidates);
|
||||||
|
RegisterSecrets(Candidates);
|
||||||
|
RegisterProjects(Candidates);
|
||||||
|
RegisterEnvironments(Candidates);
|
||||||
|
RegisterFolders(Candidates);
|
||||||
|
RegisterTags(Candidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Add(Dictionary<string, List<InfisicalEndpointDefinition>> map, InfisicalEndpointDefinition definition)
|
||||||
|
{
|
||||||
|
List<InfisicalEndpointDefinition> list;
|
||||||
|
if (!map.TryGetValue(definition.Name, out list))
|
||||||
{
|
{
|
||||||
{
|
list = new List<InfisicalEndpointDefinition>();
|
||||||
InfisicalEndpointNames.UniversalAuthLogin,
|
map[definition.Name] = list;
|
||||||
new List<InfisicalEndpointDefinition>
|
}
|
||||||
{
|
|
||||||
new InfisicalEndpointDefinition
|
list.Add(definition);
|
||||||
{
|
}
|
||||||
Name = InfisicalEndpointNames.UniversalAuthLogin,
|
|
||||||
Resource = "Authentication",
|
private static void RegisterAuthentication(Dictionary<string, List<InfisicalEndpointDefinition>> map)
|
||||||
Version = "v1",
|
{
|
||||||
Method = "POST",
|
Add(map, new InfisicalEndpointDefinition
|
||||||
Template = "/api/v1/auth/universal-auth/login",
|
{
|
||||||
RequiresAuthorization = false,
|
Name = InfisicalEndpointNames.UniversalAuthLogin,
|
||||||
ContainsSecretMaterialInRequest = true,
|
Resource = "Authentication",
|
||||||
ContainsSecretMaterialInResponse = true
|
Version = "v1",
|
||||||
}
|
Method = "POST",
|
||||||
}
|
Template = "/api/v1/auth/universal-auth/login",
|
||||||
},
|
RequiresAuthorization = false,
|
||||||
{
|
ContainsSecretMaterialInRequest = true,
|
||||||
InfisicalEndpointNames.ListSecrets,
|
ContainsSecretMaterialInResponse = true
|
||||||
new List<InfisicalEndpointDefinition>
|
});
|
||||||
{
|
|
||||||
new InfisicalEndpointDefinition
|
Add(map, new InfisicalEndpointDefinition
|
||||||
{
|
{
|
||||||
Name = InfisicalEndpointNames.ListSecrets,
|
Name = InfisicalEndpointNames.TokenAuthLogin,
|
||||||
Resource = "Secrets",
|
Resource = "Authentication",
|
||||||
Version = "v4",
|
Version = "v1",
|
||||||
Method = "GET",
|
Method = "POST",
|
||||||
Template = "/api/v4/secrets",
|
Template = "/api/v1/auth/token-auth/login",
|
||||||
RequiresAuthorization = true,
|
RequiresAuthorization = false,
|
||||||
ContainsSecretMaterialInRequest = false,
|
ContainsSecretMaterialInRequest = true,
|
||||||
ContainsSecretMaterialInResponse = true
|
ContainsSecretMaterialInResponse = true
|
||||||
},
|
});
|
||||||
new InfisicalEndpointDefinition
|
|
||||||
{
|
Add(map, new InfisicalEndpointDefinition
|
||||||
Name = InfisicalEndpointNames.ListSecrets,
|
{
|
||||||
Resource = "Secrets",
|
Name = InfisicalEndpointNames.JwtAuthLogin,
|
||||||
Version = "v3",
|
Resource = "Authentication",
|
||||||
Method = "GET",
|
Version = "v1",
|
||||||
Template = "/api/v3/secrets/raw",
|
Method = "POST",
|
||||||
RequiresAuthorization = true,
|
Template = "/api/v1/auth/jwt-auth/login",
|
||||||
ContainsSecretMaterialInRequest = false,
|
RequiresAuthorization = false,
|
||||||
ContainsSecretMaterialInResponse = true
|
ContainsSecretMaterialInRequest = true,
|
||||||
}
|
ContainsSecretMaterialInResponse = true
|
||||||
}
|
});
|
||||||
},
|
|
||||||
{
|
Add(map, new InfisicalEndpointDefinition
|
||||||
InfisicalEndpointNames.RetrieveSecret,
|
{
|
||||||
new List<InfisicalEndpointDefinition>
|
Name = InfisicalEndpointNames.OidcAuthLogin,
|
||||||
{
|
Resource = "Authentication",
|
||||||
new InfisicalEndpointDefinition
|
Version = "v1",
|
||||||
{
|
Method = "POST",
|
||||||
Name = InfisicalEndpointNames.RetrieveSecret,
|
Template = "/api/v1/auth/oidc-auth/login",
|
||||||
Resource = "Secrets",
|
RequiresAuthorization = false,
|
||||||
Version = "v4",
|
ContainsSecretMaterialInRequest = true,
|
||||||
Method = "GET",
|
ContainsSecretMaterialInResponse = true
|
||||||
Template = "/api/v4/secrets/{secretName}",
|
});
|
||||||
RequiresAuthorization = true,
|
|
||||||
ContainsSecretMaterialInRequest = false,
|
Add(map, new InfisicalEndpointDefinition
|
||||||
ContainsSecretMaterialInResponse = true
|
{
|
||||||
},
|
Name = InfisicalEndpointNames.LdapAuthLogin,
|
||||||
new InfisicalEndpointDefinition
|
Resource = "Authentication",
|
||||||
{
|
Version = "v1",
|
||||||
Name = InfisicalEndpointNames.RetrieveSecret,
|
Method = "POST",
|
||||||
Resource = "Secrets",
|
Template = "/api/v1/auth/ldap-auth/login",
|
||||||
Version = "v3",
|
RequiresAuthorization = false,
|
||||||
Method = "GET",
|
ContainsSecretMaterialInRequest = true,
|
||||||
Template = "/api/v3/secrets/raw/{secretName}",
|
ContainsSecretMaterialInResponse = true
|
||||||
RequiresAuthorization = true,
|
});
|
||||||
ContainsSecretMaterialInRequest = false,
|
|
||||||
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,
|
||||||
|
Resource = "Authentication",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "POST",
|
||||||
|
Template = "/api/v1/auth/azure-auth/login",
|
||||||
|
RequiresAuthorization = false,
|
||||||
|
ContainsSecretMaterialInRequest = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.GcpIamAuthLogin,
|
||||||
|
Resource = "Authentication",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "POST",
|
||||||
|
Template = "/api/v1/auth/gcp-auth/login",
|
||||||
|
RequiresAuthorization = false,
|
||||||
|
ContainsSecretMaterialInRequest = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RegisterSecrets(Dictionary<string, List<InfisicalEndpointDefinition>> map)
|
||||||
|
{
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.ListSecrets,
|
||||||
|
Resource = "Secrets",
|
||||||
|
Version = "v4",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v4/secrets",
|
||||||
|
RequiresAuthorization = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.ListSecrets,
|
||||||
|
Resource = "Secrets",
|
||||||
|
Version = "v3",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v3/secrets/raw",
|
||||||
|
RequiresAuthorization = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.RetrieveSecret,
|
||||||
|
Resource = "Secrets",
|
||||||
|
Version = "v4",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v4/secrets/{secretName}",
|
||||||
|
RequiresAuthorization = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.RetrieveSecret,
|
||||||
|
Resource = "Secrets",
|
||||||
|
Version = "v3",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v3/secrets/raw/{secretName}",
|
||||||
|
RequiresAuthorization = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.CreateSecret,
|
||||||
|
Resource = "Secrets",
|
||||||
|
Version = "v3",
|
||||||
|
Method = "POST",
|
||||||
|
Template = "/api/v3/secrets/raw/{secretName}",
|
||||||
|
RequiresAuthorization = true,
|
||||||
|
ContainsSecretMaterialInRequest = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.UpdateSecret,
|
||||||
|
Resource = "Secrets",
|
||||||
|
Version = "v3",
|
||||||
|
Method = "PATCH",
|
||||||
|
Template = "/api/v3/secrets/raw/{secretName}",
|
||||||
|
RequiresAuthorization = true,
|
||||||
|
ContainsSecretMaterialInRequest = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.DeleteSecret,
|
||||||
|
Resource = "Secrets",
|
||||||
|
Version = "v3",
|
||||||
|
Method = "DELETE",
|
||||||
|
Template = "/api/v3/secrets/raw/{secretName}",
|
||||||
|
RequiresAuthorization = true,
|
||||||
|
ContainsSecretMaterialInResponse = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RegisterProjects(Dictionary<string, List<InfisicalEndpointDefinition>> map)
|
||||||
|
{
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.ListProjects,
|
||||||
|
Resource = "Projects",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v1/workspace",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.RetrieveProject,
|
||||||
|
Resource = "Projects",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v1/workspace/{projectId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.CreateProject,
|
||||||
|
Resource = "Projects",
|
||||||
|
Version = "v2",
|
||||||
|
Method = "POST",
|
||||||
|
Template = "/api/v2/workspace",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.UpdateProject,
|
||||||
|
Resource = "Projects",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "PATCH",
|
||||||
|
Template = "/api/v1/workspace/{projectId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.DeleteProject,
|
||||||
|
Resource = "Projects",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "DELETE",
|
||||||
|
Template = "/api/v1/workspace/{projectId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RegisterEnvironments(Dictionary<string, List<InfisicalEndpointDefinition>> map)
|
||||||
|
{
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.ListEnvironments,
|
||||||
|
Resource = "Environments",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v1/workspace/{projectId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.RetrieveEnvironment,
|
||||||
|
Resource = "Environments",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/environments/{environmentId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.CreateEnvironment,
|
||||||
|
Resource = "Environments",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "POST",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/environments",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.UpdateEnvironment,
|
||||||
|
Resource = "Environments",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "PATCH",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/environments/{environmentId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.DeleteEnvironment,
|
||||||
|
Resource = "Environments",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "DELETE",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/environments/{environmentId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RegisterFolders(Dictionary<string, List<InfisicalEndpointDefinition>> map)
|
||||||
|
{
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.ListFolders,
|
||||||
|
Resource = "Folders",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v1/folders",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.RetrieveFolder,
|
||||||
|
Resource = "Folders",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v1/folders/{folderId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.CreateFolder,
|
||||||
|
Resource = "Folders",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "POST",
|
||||||
|
Template = "/api/v1/folders",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.UpdateFolder,
|
||||||
|
Resource = "Folders",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "PATCH",
|
||||||
|
Template = "/api/v1/folders/{folderId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.DeleteFolder,
|
||||||
|
Resource = "Folders",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "DELETE",
|
||||||
|
Template = "/api/v1/folders/{folderId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RegisterTags(Dictionary<string, List<InfisicalEndpointDefinition>> map)
|
||||||
|
{
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.ListTags,
|
||||||
|
Resource = "Tags",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/tags",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.RetrieveTag,
|
||||||
|
Resource = "Tags",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "GET",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/tags/{tagId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.CreateTag,
|
||||||
|
Resource = "Tags",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "POST",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/tags",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.UpdateTag,
|
||||||
|
Resource = "Tags",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "PATCH",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/tags/{tagId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(map, new InfisicalEndpointDefinition
|
||||||
|
{
|
||||||
|
Name = InfisicalEndpointNames.DeleteTag,
|
||||||
|
Resource = "Tags",
|
||||||
|
Version = "v1",
|
||||||
|
Method = "DELETE",
|
||||||
|
Template = "/api/v1/workspace/{projectId}/tags/{tagId}",
|
||||||
|
RequiresAuthorization = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static InfisicalEndpointDefinition Get(string name)
|
public static InfisicalEndpointDefinition Get(string name)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using PSInfisicalAPI.Connections;
|
||||||
|
using PSInfisicalAPI.Endpoints;
|
||||||
|
using PSInfisicalAPI.Errors;
|
||||||
|
using PSInfisicalAPI.Security;
|
||||||
|
|
||||||
|
namespace PSInfisicalAPI.Http
|
||||||
|
{
|
||||||
|
internal sealed class InfisicalApiInvoker
|
||||||
|
{
|
||||||
|
private readonly IInfisicalHttpClient _httpClient;
|
||||||
|
|
||||||
|
public InfisicalApiInvoker(IInfisicalHttpClient httpClient)
|
||||||
|
{
|
||||||
|
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
|
||||||
|
}
|
||||||
|
|
||||||
|
public InfisicalHttpResponse Invoke(
|
||||||
|
InfisicalConnection connection,
|
||||||
|
string endpointName,
|
||||||
|
string operationName,
|
||||||
|
IDictionary<string, string> pathParameters,
|
||||||
|
IEnumerable<KeyValuePair<string, string>> queryParameters,
|
||||||
|
string body)
|
||||||
|
{
|
||||||
|
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
|
||||||
|
if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException(nameof(endpointName)); }
|
||||||
|
|
||||||
|
InfisicalEndpointDefinition definition = InfisicalEndpointRegistry.Get(endpointName);
|
||||||
|
Uri uri = InfisicalUriBuilder.Build(connection.BaseUri, definition, pathParameters, queryParameters);
|
||||||
|
|
||||||
|
InfisicalHttpResponse response = ExecuteAuthorized(connection, definition, operationName, uri, body);
|
||||||
|
|
||||||
|
if (response.StatusCode >= 200 && response.StatusCode < 300)
|
||||||
|
{
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
InfisicalApiException exception = BuildApiException(response, definition);
|
||||||
|
response.Clear();
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
private InfisicalHttpResponse ExecuteAuthorized(
|
||||||
|
InfisicalConnection connection,
|
||||||
|
InfisicalEndpointDefinition definition,
|
||||||
|
string operationName,
|
||||||
|
Uri uri,
|
||||||
|
string body)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
headers["Accept"] = "application/json";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(body))
|
||||||
|
{
|
||||||
|
headers["Content-Type"] = "application/json";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (definition.RequiresAuthorization)
|
||||||
|
{
|
||||||
|
if (connection.AccessToken == null)
|
||||||
|
{
|
||||||
|
throw new InfisicalAuthenticationException("Connection does not contain an access token.");
|
||||||
|
}
|
||||||
|
|
||||||
|
SecureStringUtility.UsePlainText(connection.AccessToken, plainToken =>
|
||||||
|
{
|
||||||
|
headers["Authorization"] = string.Concat("Bearer ", plainToken ?? string.Empty);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
InfisicalHttpRequest request = new InfisicalHttpRequest
|
||||||
|
{
|
||||||
|
OperationName = operationName,
|
||||||
|
EndpointName = definition.Name,
|
||||||
|
Method = definition.Method,
|
||||||
|
Uri = uri,
|
||||||
|
Headers = headers,
|
||||||
|
Body = body,
|
||||||
|
ContainsSecretMaterialInRequest = definition.ContainsSecretMaterialInRequest,
|
||||||
|
ContainsSecretMaterialInResponse = definition.ContainsSecretMaterialInResponse
|
||||||
|
};
|
||||||
|
|
||||||
|
return _httpClient.Send(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InfisicalApiException BuildApiException(InfisicalHttpResponse response, InfisicalEndpointDefinition definition)
|
||||||
|
{
|
||||||
|
InfisicalApiException exception = new InfisicalApiException(string.Concat(
|
||||||
|
"Infisical API returned ",
|
||||||
|
response.StatusCode.ToString(CultureInfo.InvariantCulture),
|
||||||
|
" (", response.ReasonPhrase ?? string.Empty, ")."));
|
||||||
|
exception.StatusCode = response.StatusCode;
|
||||||
|
exception.ReasonPhrase = response.ReasonPhrase;
|
||||||
|
exception.EndpointName = definition.Name;
|
||||||
|
exception.RequestMethod = definition.Method;
|
||||||
|
exception.SanitizedBody = response.Body;
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user