Skip to content

Commit

Permalink
Invoke-TssApi - internal cmdlet for web request
Browse files Browse the repository at this point in the history
Additional scripts added to accomodate processing web request output
  • Loading branch information
wsmelton committed Aug 5, 2021
1 parent 0e7eae8 commit da45da6
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/Thycotic.SecretServer/classes/common/RequestStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Threading.Tasks;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

namespace Thycotic.PowerShell.Common
{
public class RequestStatus
{
public bool IsSuccessful { get; set; }
public int StatusCode { get; set; }
public string StatusDescription { get; set; }
public string ResponseStatus { get; set; }
}
}
121 changes: 121 additions & 0 deletions src/Thycotic.SecretServer/cmdlets/common/InvokeTssApiCmdlet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using System;
using System.Management.Automation;
using System.Net;
using RestSharp;

namespace Thycotic.SecretServer.Cmdlets
{
/// <summary>
/// <para type="synopsis">Invokes the Secret Server Rest API.</para>
/// <para type="description">Invokes the Secret Server Rest API.</para>
/// </summary>
[Cmdlet(VerbsLifecycle.Invoke, "TssApi", HelpUri = "https://thycotic-ps.github.io/thycotic.secretserver/common/Invoke-TssApi")]
public class InvokeTssApiCmdlet : PSCmdlet
{
///<summary>
///<para type="description">Full URL endpoint, e.g. https://alpha.local/SecretServer/api/v1/secrets.</para>
///</summary>
[Parameter(Mandatory = true, Position = 0)]
[Alias("Url")]
public string Uri { get; set; }

///<summary>
///<para type="description">Valid Access Token issued by Secret Server.</para>
///</summary>
[Parameter(Mandatory = true, Position = 1)]
public string AccessToken { get; set; }

///<summary>
///<para type="description">Method used for the web request, supported by Secret Server.</para>
///</summary>
[Parameter(Mandatory = true, Position = 2)]
[ValidateSet("GET", "DELETE", "PATCH", "POST", "PUT")]
public Method Method { get; set; }

///<summary>
///<para type="description">Specifies the body of the request.</para>
///</summary>
[Parameter(Position = 3)]
public object Body { get; set; }

///<summary>
///<para type="description">Specifies the file path to write the content.</para>
///</summary>
[Parameter(Position = 4)]
public string OutFile { get; set; }

///<summary>
///<para type="description">Specifies the content type of the web request.</para>
///<para type="description">If this parameter is omitted and the request method is POST, Invoke-RestMethod sets the content type to application/x-www-form-urlencoded. Otherwise, the content type is not specified in the call.</para>
///</summary>
[Parameter(Position = 5)]
public string ContentType { get; set; } = "application/json";

///<summary>
///<para type="description">Indicates using the credentials of the current user to send the web request (winauth).</para>
///</summary>
[Parameter(Position = 6)]
public SwitchParameter UseDefaultCredential { get; set; }

///<summary>
///<para type="description">Specifies that the cmdlet uses a proxy server for the request,</para>
///<para type="description">rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.</para>
///</summary>
[Parameter(Position = 7)]
public string Proxy { get; set; }

///<summary>
///<para type="description">Specifies a user account that has permission to use the proxy server that is specified by the Proxy parameter. The default is the current user.</para>
///<para type="description">This parameter is valid only when the Proxy parameter is also used in the command. You cannot use the ProxyCredential and ProxyUseDefaultCredentials parameters in the same command.</para>
///</summary>
[Parameter(Position = 8)]
public PSCredential ProxyCredential { get; set; }

///<summary>
///<para type="description">Indicates that the cmdlet uses the credentials of the current user to access the proxy server that is specified by the Proxy parameter.</para>
///<para type="description">This parameter is valid only when the Proxy parameter is also used in the command. You cannot use the ProxyCredential and ProxyUseDefaultCredentials parameters in the same command.</para>
///</summary>
[Parameter(Position = 9)]
public SwitchParameter ProxyUseDefaultCredentials { get; set; }

///<summary>
///<para type="description">Timeout in seconds for the REST client connection.</para>
///<para type="description">Default value is 0 (zero), which defaults to the http client default time of 100 seconds.</para>
///</summary>
[Parameter(Position = 10)]
public int Timeout { get; set; } = 0;

protected override void ProcessRecord()
{
Uri requestUri = new Uri(Uri);
var apiClient = new RestClient();
apiClient.BaseUrl = requestUri;
apiClient.Timeout = Timeout;

if (string.IsNullOrEmpty(Proxy))
{
apiClient.Proxy = new WebProxy(Proxy);
if (ProxyUseDefaultCredentials.IsPresent)
{
apiClient.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
}
if (MyInvocation.BoundParameters.ContainsKey("ProxyCredential"))
{
apiClient.Proxy.Credentials = new NetworkCredential(ProxyCredential.UserName, ProxyCredential.Password);
}
}

var apiRequest = new RestRequest(Method);
apiRequest.AddHeader("Content-Type", ContentType);
apiRequest.AddHeader("Authorization", "Bearer " + AccessToken);

if (MyInvocation.BoundParameters.ContainsKey("Body"))
{
apiRequest.AddParameter("application/json", Body , ParameterType.RequestBody);
}

IRestResponse apiResponse = apiClient.Execute(apiRequest);
WriteObject(apiResponse);
}
}
}
18 changes: 18 additions & 0 deletions src/parts/GetInvokeApiParams.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
param(
[Parameter(ValueFromPipeline,Position = 0,Mandatory)]
[Thycotic.PowerShell.Authentication.Session]
$TssSession
)

process {
$getInvokeParams = @{}
switch ($TssSession.TokenType) {
'WindowsAuth' {
$getInvokeParams.UseDefaultCredential = $true
}
default {
$getInvokeParams.AccessToken = $TssSession.AccessToken
}
}
return $getInvokeParams
}
27 changes: 27 additions & 0 deletions src/parts/ProcessResponse.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[cmdletbinding()]
param(
[Parameter(Mandatory, Position = 0)]
[RestSharp.RestResponse]
$Response
)

if ($Response.Content.StartsWith("{") -and $Response.Content.EndsWith("}")) {
$content = $Response.Content | ConvertFrom-Json -Depth 50
} else {
$content = $Response.Content
}

$requestStatus = [Thycotic.PowerShell.Common.RequestStatus]@{
StatusCode = [int]$Response.StatusCode
StatusDescription = $Response.StatusDescription
IsSuccessful = $Response.IsSuccessful
ResponseStatus = $Response.ResponseStatus
}
New-Variable -Name tssLastResponse -Value $requestStatus -Description "Contains request status object for the command's last web request" -Visibility Public -Scope Global -Force

if (-not $Response.IsSuccessful) {
$errorContent = $Response.Content
$PSCmdlet.WriteError([Management.Automation.ErrorRecord]::new([Exception]::new($errorContent),"ResultError", "NotSpecified", $invokeParams.Uri))
} else {
return $content
}

0 comments on commit da45da6

Please sign in to comment.