Skip to content

Commit

Permalink
Release V1.3.0.2 - Bugfixes
Browse files Browse the repository at this point in the history
Merge pull request #43 from AndiBellstedt/Development
  • Loading branch information
AndiBellstedt authored Sep 16, 2023
2 parents 7bee2b9 + e9181d2 commit f024021
Show file tree
Hide file tree
Showing 32 changed files with 160 additions and 318 deletions.
7 changes: 4 additions & 3 deletions MSGraph/MSGraph.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
RootModule = 'MSGraph.psm1'

# Version number of this module.
ModuleVersion = '1.3.0.0'
ModuleVersion = '1.3.0.2'

# ID used to uniquely identify this module
GUID = '5f61c229-95d0-4423-ab50-938c0723ad21'
Expand Down Expand Up @@ -179,7 +179,8 @@
## Attachments
'Save-MgaMailAttachment',

# COre
# Core
'Connect-MgaGraph',
'Invoke-MgaDeleteMethod'
'Invoke-MgaGetMethod',
'Invoke-MgaPatchMethod',
Expand Down Expand Up @@ -233,7 +234,7 @@
ProjectUri = 'https://github.com/AndiBellstedt/MSGraph'

# A URL to an icon representing this module.
IconUri = 'https://github.com/AndiBellstedt/MSGraph/tree/Development/MSGraph/assets/MSGraph_128x128.png'
IconUri = 'https://github.com/AndiBellstedt/MSGraph/raw/master/assets/MSGraph_128x128.png'

# ReleaseNotes of this module
ReleaseNotes = 'https://github.com/AndiBellstedt/MSGraph/blob/master/MSGraph/changelog.md'
Expand Down
Binary file modified MSGraph/bin/MSGraph.dll
Binary file not shown.
Binary file modified MSGraph/bin/MSGraph.pdb
Binary file not shown.
7 changes: 5 additions & 2 deletions MSGraph/bin/MSGraph.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified MSGraph/bin/System.Management.Automation.dll
Binary file not shown.
10 changes: 10 additions & 0 deletions MSGraph/changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# Changelog
## 1.3.0.2
- Fix:
- Fixing date issue on Mail-Items in PS7 (PS5.1 was working fine)
- Upd:
- Change default permission for New-MgaAccessToken (Connect-MgaGraph)\
Function is connecting with simple "login" permissions by default. Previously Mail.Read was default. Due to the fact, that there are other functions in the module, this might be a permission not necessary and it would not follow “least-privilege”, the permission was removed
## 1.3.0.1
- New: Alias Connect-MgaGraph
- Introducing a alias on command New-MgaAccessToken, for convinience
- Fix: Fixing some typos
## 1.3.0.0
- New: Command Get-MgaTeam
- returns information about Microsoft Teams team(s)
Expand Down
2 changes: 2 additions & 0 deletions MSGraph/functions/core/Invoke-MgaRestMethodDelete.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@
try {
$data = Invoke-RestMethod @invokeParam -ErrorVariable "restError" -ErrorAction Stop -Verbose:$false -UseBasicParsing
} catch {
Remove-Variable -Name invokeParam -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false -ErrorAction:SilentlyContinue
Stop-PSFFunction -Tag "RestDataError" -Message $_.Exception.Message -Exception $_.Exception -ErrorRecord $_ -EnableException $true -Category ConnectionError -FunctionName $FunctionName
}
Remove-Variable -Name invokeParam -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false -ErrorAction:SilentlyContinue
}

if ($data) {
Expand Down
8 changes: 4 additions & 4 deletions MSGraph/functions/core/Invoke-MgaRestMethodGet.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
if ($Delta) { $restUri = $restUri + "/delta" }
}
if ($ResultSize -eq 0) { $ResultSize = [Int64]::MaxValue }
#if ($ResultSize -le 10 -and $restUri -notmatch '\$top=') { $restUri = $restUri + "?`$top=$($ResultSize)" }
[Int64]$i = 0
[Int64]$overResult = 0
$tooManyItems = $false
Expand All @@ -127,8 +126,10 @@
try {
$data = Invoke-RestMethod @invokeParam -ErrorVariable "restError" -ErrorAction Stop -Verbose:$false -UseBasicParsing
} catch {
Remove-Variable -Name invokeParam -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false -ErrorAction:SilentlyContinue
Stop-PSFFunction -Tag "RestDataError" -Message $_.Exception.Message -Exception $_.Exception -ErrorRecord $_ -EnableException $true -Category ConnectionError -FunctionName $FunctionName
}
Remove-Variable -Name invokeParam -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false -ErrorAction:SilentlyContinue

if ("Value" -in $data.psobject.Properties.Name) {
# Multi object with value property returned by api call
Expand All @@ -144,7 +145,7 @@
Write-PSFMessage -Tag "ResultSize" -Level Verbose -Message "Resultsize ($ResultSize) exeeded. Output $($overResult) object(s) in record set."
}
} else {
# Multi object with value property returned by api call
# Single object without value property returned by api call
Write-PSFMessage -Tag "RestData" -Level VeryVerbose -Message "Single item retrived. Outputting data."
[array]$value = $data
$restUri = ""
Expand All @@ -158,8 +159,7 @@
$output = $output + $Value
}
}
}
while ($restUri)
} while ($restUri)
#endregion query data

#region output data
Expand Down
2 changes: 2 additions & 0 deletions MSGraph/functions/core/Invoke-MgaRestMethodPatch.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@
try {
$data = Invoke-RestMethod @invokeParam -ErrorVariable "restError" -ErrorAction Stop -Verbose:$false -UseBasicParsing
} catch {
Remove-Variable -Name invokeParam -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false -ErrorAction:SilentlyContinue
Stop-PSFFunction -Tag "RestDataError" -Message $_.Exception.Message -Exception $_.Exception -ErrorRecord $_ -EnableException $true -Category ConnectionError -FunctionName $FunctionName
}
Remove-Variable -Name invokeParam -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false -ErrorAction:SilentlyContinue

if ($data) {
$data | Add-Member -MemberType NoteProperty -Name 'User' -Value $User -Force
Expand Down
2 changes: 2 additions & 0 deletions MSGraph/functions/core/Invoke-MgaRestMethodPost.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@
try {
$data = Invoke-RestMethod @invokeParam -ErrorVariable "restError" -ErrorAction Stop -Verbose:$false -UseBasicParsing
} catch {
Remove-Variable -Name invokeParam -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false -ErrorAction:SilentlyContinue
Stop-PSFFunction -Tag "RestDataError" -Message $_.Exception.Message -Exception $_.Exception -ErrorRecord $_ -EnableException $true -Category ConnectionError -FunctionName $FunctionName
}
Remove-Variable -Name invokeParam -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false -ErrorAction:SilentlyContinue

if ($restError) {
Stop-PSFFunction -Tag "RestData" -Message $parseError[0].Exception -Exception $parseError[0].Exception -EnableException $false -Category ConnectionError -FunctionName $FunctionName
Expand Down
41 changes: 30 additions & 11 deletions MSGraph/functions/core/New-MgaAccessToken.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
[CmdletBinding(DefaultParameterSetName = "LoginWithWebForm")]
[Alias('Connect-MgaGraph')]
param (
[Parameter(ParameterSetName = 'LoginWithCredentialObject')]
[PSCredential]
Expand Down Expand Up @@ -116,24 +117,23 @@
[switch]
$PassThru
)

begin {
$baselineTimestamp = [datetime]"1970-01-01Z00:00:00"
$endpointBaseUri = (Get-PSFConfigValue -FullName MSGraph.Tenant.Authentiation.Endpoint -Fallback 'https://login.microsoftonline.com')

if ($IdentityPlatformVersion -like '1.0' -and $Permission) {
Write-PSFMessage -Level Warning -Message "Individual pemissions are not supported in combination with IdentityPlatformVersion 1.0. Specified Permission ($([String]::Join(", ", $Permission))) in parameter will be ignored" -Tag "ParameterSetHandling"
$Permission = ""
} elseif ($IdentityPlatformVersion -like '2.0' -and (-not $Permission)) {
$Permission = @("Mail.ReadWrite.Shared")
}
}

process {
# variable definitions
#region variable definitions
switch ($IdentityPlatformVersion) {
'1.0' { $endpointUri = "$($endpointBaseUri)/$($Tenant)/oauth2" }
'2.0' {
if ($Credential -and $Tenant -notlike "organizations") {
if ($Credential -and ($Tenant -notlike "organizations")) {
$endpointUri = "$($endpointBaseUri)/organizations/oauth2/V2.0"
} else {
$endpointUri = "$($endpointBaseUri)/$($Tenant)/oauth2/V2.0"
Expand All @@ -155,6 +155,8 @@
Remove-Variable -Name scopes -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false
Write-PSFMessage -Level VeryVerbose -Message "Using scope: $($scope)" -Tag "Authorization"
}
#endregion variable definitions


#region Request an authorization code (login procedure)
if (-not $Credential) {
Expand All @@ -180,12 +182,14 @@
}

# Show login windows (web form)
$phase1auth = Show-OAuthWindow -Url ($endpointUriAuthorize + (Convert-UriQueryFromHash $queryHash))
[string]$url = $endpointUriAuthorize + (Convert-UriQueryFromHash $queryHash)
$phase1auth = Show-OAuthWindow -Url $url
if (-not $phase1auth.code) {
$msg = "Authentication failed. Unable to obtain AccessToken.`n$($phase1auth.error_description)"
if ($phase1auth.error) { $msg = $phase1auth.error.ToUpperInvariant() + " - " + $msg }
Stop-PSFFunction -Message $msg -Tag "Authorization" -EnableException $true -Exception ([System.Management.Automation.RuntimeException]::new($msg))
}
Remove-Variable -Name url -Force -WhatIf:$false -Confirm:$false -Verbose:$false -Debug:$false

# build authorization string with authentication code from web form auth
$tokenQueryHash = [ordered]@{
Expand Down Expand Up @@ -219,20 +223,24 @@
}
#endregion Request an authorization code (login procedure)

# Request an access token
$content = New-Object System.Net.Http.StringContent($authorizationPostRequest, [System.Text.Encoding]::UTF8, "application/x-www-form-urlencoded")

#region Request an access token
$content = New-Object -TypeName "System.Net.Http.StringContent" -ArgumentList ($authorizationPostRequest, [System.Text.Encoding]::UTF8, "application/x-www-form-urlencoded")
$httpClient = New-HttpClient
$clientResult = $httpClient.PostAsync([Uri]($endpointUriToken), $content)
$jsonResponse = ConvertFrom-Json -InputObject $clientResult.Result.Content.ReadAsStringAsync().Result -ErrorAction Ignore
if ($clientResult.Result.StatusCode -eq [System.Net.HttpStatusCode]"OK") {
Write-PSFMessage -Level Verbose -Message "AccessToken granted. $($clientResult.Result.StatusCode.value__) ($($clientResult.Result.StatusCode)) $($clientResult.Result.ReasonPhrase)" -Tag "Authorization"
} else {
$httpClient.CancelPendingRequests()
$msg = "Request for AccessToken failed. $($clientResult.Result.StatusCode.value__) ($($clientResult.Result.StatusCode)) $($clientResult.Result.ReasonPhrase) `n$($jsonResponse.error_description)"
Stop-PSFFunction -Message $msg -Tag "Authorization" -EnableException $true -Exception ([System.Management.Automation.RuntimeException]::new($msg))
}
#endregion Request an access token


#region Build output object
$jsonResponse = ConvertFrom-Json -InputObject $clientResult.Result.Content.ReadAsStringAsync().Result -ErrorAction Ignore

# Build output object
$resultObject = New-Object -TypeName MSGraph.Core.AzureAccessToken -Property @{
IdentityPlatformVersion = $IdentityPlatformVersion
TokenType = $jsonResponse.token_type
Expand All @@ -244,6 +252,7 @@
Resource = $resourceUri
AppRedirectUrl = $RedirectUrl
}

switch ($IdentityPlatformVersion) {
'1.0' {
$resultObject.Scope = $jsonResponse.scope -split " "
Expand All @@ -262,7 +271,9 @@
}

# Insert token data into output object. done as secure string to prevent text output of tokens
if ($jsonResponse.psobject.Properties.name -contains "refresh_token") { $resultObject.RefreshToken = ($jsonResponse.refresh_token | ConvertTo-SecureString -AsPlainText -Force) }
if ($jsonResponse.psobject.Properties.name -contains "refresh_token") {
$resultObject.RefreshToken = ($jsonResponse.refresh_token | ConvertTo-SecureString -AsPlainText -Force)
}
if ($jsonResponse.psobject.Properties.name -contains "id_token") {
$resultObject.IDToken = ($jsonResponse.id_token | ConvertTo-SecureString -AsPlainText -Force)
$resultObject.AccessTokenInfo = ConvertFrom-JWTtoken -Token $jsonResponse.id_token
Expand All @@ -275,13 +286,18 @@
}

# Getting validity period out of AccessToken information
if ($resultObject.AccessTokenInfo -and $resultObject.AccessTokenInfo.TenantID.ToString() -notlike "9188040d-6c67-4c5b-b112-36a304b66dad") {
if ($resultObject.AccessTokenInfo -and
($resultObject.AccessTokenInfo.TenantID.ToString() -notlike "9188040d-6c67-4c5b-b112-36a304b66dad")
) {
$resultObject.ValidUntilUtc = $resultObject.AccessTokenInfo.ExpirationTime.ToUniversalTime()
$resultObject.ValidFromUtc = $resultObject.AccessTokenInfo.NotBefore.ToUniversalTime()
$resultObject.ValidUntil = $resultObject.AccessTokenInfo.ExpirationTime.ToLocalTime().AddHours( [int]$resultObject.AccessTokenInfo.ExpirationTime.ToLocalTime().IsDaylightSavingTime() )
$resultObject.ValidFrom = $resultObject.AccessTokenInfo.NotBefore.ToLocalTime().AddHours( [int]$resultObject.AccessTokenInfo.NotBefore.ToLocalTime().IsDaylightSavingTime() )
}
#endregion Build output object


#region Output the object
# Checking if token is valid
# ToDo implement "validating token information" -> https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens#validating-tokens
if ($resultObject.IsValid) {
Expand All @@ -294,5 +310,8 @@
} else {
Stop-PSFFunction -Message "Token failure. Acquired token is not valid" -EnableException $true -Tag "Authorization"
}
#endregion Output the object
}

end {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
[MSGraph.Core.AzureAccessToken]
$Token
)

begin {
$requiredPermission = "Mail.Read"
$Token = Invoke-TokenScopeValidation -Token $Token -Scope $requiredPermission -FunctionName $MyInvocation.MyCommand
Expand Down
1 change: 1 addition & 0 deletions MSGraph/internal/functions/core/ConvertFrom-JWTtoken.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
$resultObject.Type = $tokenHeaderJSON.typ
if ($tokenPayloadJSON.appid) { $resultObject.ApplicationID = $tokenPayloadJSON.appid }
$resultObject.ApplicationName = $tokenPayloadJSON.app_displayname
$resultObject.Issuer = $tokenPayloadJSON.iss
$resultObject.Audience = $tokenPayloadJSON.aud
$resultObject.AuthenticationMethod = $tokenPayloadJSON.amr
$resultObject.ExpirationTime = ([datetime]"1970-01-01Z00:00:00").AddSeconds($tokenPayloadJSON.exp).ToUniversalTime()
Expand Down
57 changes: 44 additions & 13 deletions MSGraph/internal/functions/core/Show-OAuthWindow.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,67 @@
$Url
)

process {
$web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{
Width = 420
Height = 600
Url = $Url
begin {}

process {}

end {
# check screen resultion and calculate size for login form
$screenResolution = Get-CimInstance -ClassName Win32_VideoController
$formWidth = [math]::round(($screenResolution.CurrentHorizontalResolution / 4.36), 0)
$formHeight = [math]::round(($screenResolution.CurrentVerticalResolution / 1.69), 0)
if ($formWidth -lt 440) { $formWidth = 440 }
if ($formHeight -lt 640) { $formHeight = 640 }

# Create form object
$form = New-Object -TypeName "System.Windows.Forms.Form" -Property @{
Width = $formWidth #440
Height = $formHeight #640
}
$web.ScriptErrorsSuppressed = $true

# Create web browser object
$web = New-Object -TypeName "System.Windows.Forms.WebBrowser" -Property @{
Url = $Url
ClientSize = $form.ClientSize
ScriptErrorsSuppressed = $true
}

#region Event actions
# parse code or error message from URL, when Login is completed
$web.Add_DocumentCompleted( {
if ($web.Url.AbsoluteUri -match "error=[^&]*|code=[^&]*") { $form.Close() }
})
} )

$form = New-Object -TypeName System.Windows.Forms.Form -Property @{
Width = 440
Height = 640
}
$form.Controls.Add($web)
# Things to do when form is opened/shown
$form.Add_Shown( {
$form.BringToFront()
$null = $form.Focus()
$form.Activate()
$web.Navigate($Url)
})
$form.Text = $web.DocumentTitle
} )

# make form resizeable
$form.Add_Resize( {
$web.ClientSize = $form.ClientSize
$form.Text = $web.DocumentTitle
} )
#endregion Event actions

# Add browser to windows form
$form.Controls.Add($web)

# Show form to the user
$null = $form.ShowDialog()

# Get result from uri (query string within the uri)
$queryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)
$output = @{}
foreach ($key in $queryOutput.Keys) {
$output["$key"] = $queryOutput[$key]
}

# output result
[pscustomobject]$output
}
}
Loading

0 comments on commit f024021

Please sign in to comment.