Classes/004-RedditOAuthToken.ps1
<# .NOTES Created with: VSCode Created on: 5/05/2017 02:48 PM Edited on: 5/15/2017 Created by: Mark Kraus Organization: Filename: 004-RedditOAuthToken.ps1 .DESCRIPTION RedditOAuthToken Class #> Class RedditOAuthToken { [RedditApplication]$Application [datetime]$IssueDate [datetime]$ExpireDate [datetime]$LastApiCall [string]$ExportPath [RedditOAuthScope[]]$Scope [guid]$GUID = [guid]::NewGuid() [string]$Notes [string]$TokenType [RedditOAuthGrantType]$GrantType [int]$RateLimitUsed [int]$RateLimitRemaining [int]$RateLimitRest [string]$DeviceId hidden [pscredential]$TokenCredential hidden [pscredential]$RefreshCredential hidden [Microsoft.PowerShell.Commands.WebRequestSession]$Session = [Microsoft.PowerShell.Commands.WebRequestSession]::new() static [string] $AuthBaseURL = 'https://www.reddit.com/api/v1/access_token' RedditOAuthToken () {} RedditOAuthToken ( [RedditOAuthGrantType]$GrantType, [RedditApplication]$Application, [Object]$Response ) { #URI Handler If ($Response.psobject.typenames -contains 'system.uri') { if (-not $Response.Fragment) { $Exception = [System.ArgumentException]::New( "Response does not include Fragment" ) $Exception | Add-Member -Name Uri -MemberType NoteProperty -Value $Response Throw $Exception } $Content = @{} $Parsed = [System.Web.HttpUtility]:: ParseQueryString($Response.Fragment -replace '^#') $Parsed.Getenumerator() | ForEach-Object { $Content.Add($_, $Parsed[$_]) } } #WebResponse Handler Else { If ( -not ($Response.Headers.'Content-type' -match 'application/json')) { $Exception = [System.ArgumentException]::New( "Response Content-Type is not 'application/json'" ) $Exception | Add-Member -Name Response -MemberType NoteProperty -Value $Response Throw $Exception } $Content = $Response.Content | ConvertFrom-Json -ErrorAction Stop } # Do the needful $This.GrantType = $GrantType $This.Application = $Application $This.DeviceId = $Content.DeviceId $This.IssueDate = Get-Date $This.LastApiCall = $This.IssueDate $This.TokenType = $Content.token_type $This.Scope = $Content.Scope -split ' ' $This.ExpireDate = (get-date).AddSeconds($Content.expires_in) $This.RateLimitRemaining = 60 $This.RateLimitUsed = 0 $This.RateLimitRest = 60 if ($Content.access_token) { $SecString = $Content.access_token | ConvertTo-SecureString -AsPlainText -Force $This.TokenCredential = [pscredential]::new('access_token', $SecString) } if ($Content.refresh_token) { $SecString = $Content.refresh_token | ConvertTo-SecureString -AsPlainText -Force $This.RefreshCredential = [pscredential]::new('refresh_token', $SecString) } } [datetime] GetRateLimitReset() { return ($This.LastApiCall).AddSeconds($This.RateLimitRest) } [bool]IsRateLimited() { $Now = Get-date $Reset = $This.GetRateLimitReset() if ($now -ge $Reset) { return $False } if ($Now -lt $Reset -and $This.RateLimitRemaining -gt 0) { return $false } return $true } [bool] IsExpired() { return ((get-date) -ge $This.ExpireDate) } [string] GetAccessToken() { return $This.TokenCredential.GetNetworkCredential().Password } [string] GetRefreshToken() { return $This.RefreshCredential.GetNetworkCredential().Password } [string] ToString() { Return ('GUID: {0} Expires: {1}' -f $This.GUID, $This.ExpireDate) } [void] Refresh ([Object]$Response) { #URI Handler If ($Response.psobject.typenames -contains 'system.uri') { if (-not $Response.Fragment) { $Exception = [System.ArgumentException]::New( "Response does not include Fragment" ) $Exception | Add-Member -Name Uri -MemberType NoteProperty -Value $Response Throw $Exception } $Content = @{} $Parsed = [System.Web.HttpUtility]:: ParseQueryString($Response.Fragment -replace '^#') $Parsed.Getenumerator() | ForEach-Object { $Content.Add($_, $Parsed[$_]) } } #WebResponse Handler Else { If ( -not ($Response.Headers.'Content-type' -match 'application/json')) { $Exception = [System.ArgumentException]::New( "Response Content-Type is not 'application/json'" ) $Exception | Add-Member -Name Response -MemberType NoteProperty -Value $Response Throw $Exception } $Content = $Response.Content | ConvertFrom-Json -ErrorAction Stop } # Do the needful $This.IssueDate = Get-Date $This.TokenType = $Content.token_type $This.Scope = $Content.Scope -split ' ' $This.ExpireDate = (get-date).AddSeconds($Content.expires_in) if ($Content.access_token) { $SecString = $Content.access_token | ConvertTo-SecureString -AsPlainText -Force $This.TokenCredential = [pscredential]::new('access_token', $SecString) } } [void] UpdateRateLimit ([Object]$Response) { $This.RateLimitRemaining = $Response.Headers.'x-ratelimit-remaining' $This.RateLimitUsed = $Response.Headers.'x-ratelimit-used' $This.RateLimitRest = $Response.Headers.'x-ratelimit-reset' $This.LastApiCall = $Response.Headers.date } Static [RedditOAuthToken] Reserialize ([Object]$Object) { $Token = [RedditOAuthToken]::new() $Properties = $object.psobject.properties.name | Where-Object {-not ($_ -like 'Session' )} Foreach ($Property in $Properties) { $Token.$Property = $Object.$Property } return $Token } } |