diff --git a/CHANGELOG.md b/CHANGELOG.md index 96d6f1cf9..ed433d96f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - SharePointDsc - Added automatic release with a new CI pipeline - Updated PULL_REQUEST_TEMPLATE.md to match DSC standard +- SPAzureAccessControlServiceAppProxy + - Added new resource to create Azure Access Control Service Application Proxy - SPFarm - Added possibility to set application credential key. +- SPOAppPrincipalMgmtServiceAppProxy + - Added new resource to create SharePoint Online Application Principal + Management Service Application Proxy - SPTrustedSecurityTokenIssuer - Fixed RegisteredIssuerNameRealm not applied if specified. diff --git a/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/MSFT_SPAzureAccessControlServiceAppProxy.psm1 b/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/MSFT_SPAzureAccessControlServiceAppProxy.psm1 new file mode 100644 index 000000000..3803bfe90 --- /dev/null +++ b/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/MSFT_SPAzureAccessControlServiceAppProxy.psm1 @@ -0,0 +1,199 @@ +$script:resourceModulePath = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent +$script:modulesFolderPath = Join-Path -Path $script:resourceModulePath -ChildPath 'Modules' +$script:resourceHelperModulePath = Join-Path -Path $script:modulesFolderPath -ChildPath 'SharePointDsc.Util' +Import-Module -Name (Join-Path -Path $script:resourceHelperModulePath -ChildPath 'SharePointDsc.Util.psm1') + +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $MetadataServiceEndpointUri, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter()] + [System.Management.Automation.PSCredential] + $InstallAccount + ) + + Write-Verbose -Message "Getting ACS service app proxy '$Name'" + + $result = Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + $serviceAppProxy = Get-SPServiceApplicationProxy ` + | Where-Object -FilterScript { + $_.Name -eq $params.Name -and ` + $_.GetType().FullName -eq "Microsoft.SharePoint.Administration.SPAzureAccessControlServiceApplicationProxy" + } + $nullReturn = @{ + Name = $params.Name + MetadataServiceEndpointUri = $null + Ensure = "Absent" + InstallAccount = $params.InstallAccount + } + if ($null -eq $serviceAppProxy) + { + return $nullReturn + } + else + { + $returnVal = @{ + Name = $serviceAppProxy.Name + MetadataServiceEndpointUri = $serviceAppProxy.MetadataEndpointUri.OriginalString + Ensure = "Present" + InstallAccount = $params.InstallAccount + } + return $returnVal + } + } + return $result +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $MetadataServiceEndpointUri, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter()] + [System.Management.Automation.PSCredential] + $InstallAccount + ) + + Write-Verbose -Message "Setting ACS service app proxy '$Name'" + + $result = Get-TargetResource @PSBoundParameters + + if ($result.Ensure -eq "Absent" -and $Ensure -eq "Present") + { + # The service app proxy doesn't exist but should + Write-Verbose -Message "Creating ACS service app proxy $Name" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + New-SPAzureAccessControlServiceApplicationProxy -Name $params.Name ` + -MetadataServiceEndpointUri $params.MetadataServiceEndpointUri + } + } + + if ($result.Ensure -eq "Present" -and $Ensure -eq "Present") + { + # The service app proxy exists but has the wrong Metadata Service Endpoint Uri + if ($MetadataServiceEndpointUri -ne $result.MetadataServiceEndpointUri) + { + Write-Verbose -Message "Recreating ACS service app proxy $Name" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + Get-SPServiceApplicationProxy ` + | Where-Object -FilterScript { + $_.Name -eq $params.Name -and ` + $_.GetType().FullName -eq "Microsoft.SharePoint.Administration.SPAzureAccessControlServiceApplicationProxy" + } ` + | ForEach-Object { + Remove-SPServiceApplicationProxy $_ -Confirm:$false + } + + New-SPAzureAccessControlServiceApplicationProxy -Name $params.Name ` + -MetadataServiceEndpointUri $params.MetadataServiceEndpointUri + } + } + } + + if ($Ensure -eq "Absent") + { + # The service app proxy should not exit + Write-Verbose -Message "Removing ACS service app proxy $Name" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + Get-SPServiceApplicationProxy | Where-Object -FilterScript { + $_.Name -eq $params.Name -and ` + $_.GetType().FullName -eq "Microsoft.SharePoint.Administration.SPAzureAccessControlServiceApplicationProxy" + } | ForEach-Object { + Remove-SPServiceApplicationProxy $_ -Confirm:$false + } + } + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $MetadataServiceEndpointUri, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter()] + [System.Management.Automation.PSCredential] + $InstallAccount + ) + + Write-Verbose -Message "Testing ACS service app proxy '$Name'" + + $PSBoundParameters.Ensure = $Ensure + + $CurrentValues = Get-TargetResource @PSBoundParameters + + Write-Verbose -Message "Current Values: $(Convert-SPDscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-SPDscHashtableToString -Hashtable $PSBoundParameters)" + + if ($Ensure -eq "Present") + { + return Test-SPDscParameterState -CurrentValues $CurrentValues ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @("MetadataServiceEndpointUri", "Ensure") + } + else + { + return Test-SPDscParameterState -CurrentValues $CurrentValues ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @("Ensure") + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/MSFT_SPAzureAccessControlServiceAppProxy.schema.mof b/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/MSFT_SPAzureAccessControlServiceAppProxy.schema.mof new file mode 100644 index 000000000..b81d36beb --- /dev/null +++ b/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/MSFT_SPAzureAccessControlServiceAppProxy.schema.mof @@ -0,0 +1,9 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SPAzureAccessControlServiceAppProxy")] +class MSFT_SPAzureAccessControlServiceAppProxy : OMI_BaseResource +{ + [Key, Description("The name of the Azure Access Control service application proxy")] string Name; + [Write, Description("Present ensures service app proxy exists, absent ensures it is removed"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Required, Description("Specifies the URL of the Azure Access Control Service's metadata document.")] string MetadataServiceEndpointUri; + [Write, Description("POWERSHELL 4 ONLY: The account to run this resource as, use PsDscRunAsCredential if using PowerShell 5"), EmbeddedInstance("MSFT_Credential")] String InstallAccount; +}; + diff --git a/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/readme.md b/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/readme.md new file mode 100644 index 000000000..77f37526d --- /dev/null +++ b/SharePointDsc/DSCResources/MSFT_SPAzureAccessControlServiceAppProxy/readme.md @@ -0,0 +1,14 @@ +# Description + +**Type:** Distributed +**Requires CredSSP:** No + +This resource is used to create a new service application proxy for the Azure +Control service application. It will identify an instance of the ACS service +application proxy through the display name. Currently the resource will +provision the app proxy if it does not yet exist, and will recreate the proxy +if the metadata service endpoint URI associated to the proxy does not match the +configuration. + +The default value for the Ensure parameter is Present. When not specifying this +parameter, the service application proxy is provisioned. diff --git a/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/MSFT_SPOAppPrincipalMgmtServiceAppProxy.psm1 b/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/MSFT_SPOAppPrincipalMgmtServiceAppProxy.psm1 new file mode 100644 index 000000000..adf8990dc --- /dev/null +++ b/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/MSFT_SPOAppPrincipalMgmtServiceAppProxy.psm1 @@ -0,0 +1,199 @@ +$script:resourceModulePath = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent +$script:modulesFolderPath = Join-Path -Path $script:resourceModulePath -ChildPath 'Modules' +$script:resourceHelperModulePath = Join-Path -Path $script:modulesFolderPath -ChildPath 'SharePointDsc.Util' +Import-Module -Name (Join-Path -Path $script:resourceHelperModulePath -ChildPath 'SharePointDsc.Util.psm1') + +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $OnlineTenantUri, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter()] + [System.Management.Automation.PSCredential] + $InstallAccount + ) + + Write-Verbose -Message "Getting SPO application principal management service app proxy '$Name'" + + $result = Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + $serviceAppProxy = Get-SPServiceApplicationProxy ` + | Where-Object -FilterScript { + $_.Name -eq $params.Name -and ` + $_.GetType().FullName -eq "Microsoft.SharePoint.Administration.SPOnlineApplicationPrincipalManagementServiceApplicationProxy" + } + $nullReturn = @{ + Name = $params.Name + OnlineTenantUri = $null + Ensure = "Absent" + InstallAccount = $params.InstallAccount + } + if ($null -eq $serviceAppProxy) + { + return $nullReturn + } + else + { + $returnVal = @{ + Name = $serviceAppProxy.Name + OnlineTenantUri = $serviceAppProxy.OnlineTenantUri.OriginalString + Ensure = "Present" + InstallAccount = $params.InstallAccount + } + return $returnVal + } + } + return $result +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $OnlineTenantUri, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter()] + [System.Management.Automation.PSCredential] + $InstallAccount + ) + + Write-Verbose -Message "Setting SPO application principal management service app proxy '$Name'" + + $result = Get-TargetResource @PSBoundParameters + + if ($result.Ensure -eq "Absent" -and $Ensure -eq "Present") + { + # The service app proxy doesn't exist but should + Write-Verbose -Message "Creating SPO application principal management service app proxy $Name" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + New-SPOnlineApplicationPrincipalManagementServiceApplicationProxy -Name $params.Name ` + -OnlineTenantUri $params.OnlineTenantUri + } + } + + if ($result.Ensure -eq "Present" -and $Ensure -eq "Present") + { + # The service app proxy exists but has the wrong Online Tenant Uri + if ($OnlineTenantUri -ne $result.OnlineTenantUri) + { + Write-Verbose -Message "Recreating SPO application principal management service app proxy $Name" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + Get-SPServiceApplicationProxy ` + | Where-Object -FilterScript { + $_.Name -eq $params.Name -and ` + $_.GetType().FullName -eq "Microsoft.SharePoint.Administration.SPOnlineApplicationPrincipalManagementServiceApplicationProxy" + } ` + | ForEach-Object { + Remove-SPServiceApplicationProxy $_ -Confirm:$false + } + + New-SPOnlineApplicationPrincipalManagementServiceApplicationProxy -Name $params.Name ` + -OnlineTenantUri $params.OnlineTenantUri + } + } + } + + if ($Ensure -eq "Absent") + { + # The service app proxy should not exit + Write-Verbose -Message "Removing SPO application principal management service app proxy $Name" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + Get-SPServiceApplicationProxy | Where-Object -FilterScript { + $_.Name -eq $params.Name -and ` + $_.GetType().FullName -eq "Microsoft.SharePoint.Administration.SPOnlineApplicationPrincipalManagementServiceApplicationProxy" + } | ForEach-Object { + Remove-SPServiceApplicationProxy $_ -Confirm:$false + } + } + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $OnlineTenantUri, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter()] + [System.Management.Automation.PSCredential] + $InstallAccount + ) + + Write-Verbose -Message "Testing SPO application principal management service app proxy '$Name'" + + $PSBoundParameters.Ensure = $Ensure + + $CurrentValues = Get-TargetResource @PSBoundParameters + + Write-Verbose -Message "Current Values: $(Convert-SPDscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-SPDscHashtableToString -Hashtable $PSBoundParameters)" + + if ($Ensure -eq "Present") + { + return Test-SPDscParameterState -CurrentValues $CurrentValues ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @("OnlineTenantUri", "Ensure") + } + else + { + return Test-SPDscParameterState -CurrentValues $CurrentValues ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @("Ensure") + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/MSFT_SPOAppPrincipalMgmtServiceAppProxy.schema.mof b/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/MSFT_SPOAppPrincipalMgmtServiceAppProxy.schema.mof new file mode 100644 index 000000000..ad674c1ad --- /dev/null +++ b/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/MSFT_SPOAppPrincipalMgmtServiceAppProxy.schema.mof @@ -0,0 +1,9 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SPOAppPrincipalMgmtServiceAppProxy")] +class MSFT_SPOAppPrincipalMgmtServiceAppProxy : OMI_BaseResource +{ + [Key, Description("The name of the SPO application principal management service application proxy")] string Name; + [Write, Description("Present ensures service app proxy exists, absent ensures it is removed"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Required, Description("URL to SharePoint Online Tenant")] string OnlineTenantUri; + [Write, Description("POWERSHELL 4 ONLY: The account to run this resource as, use PsDscRunAsCredential if using PowerShell 5"), EmbeddedInstance("MSFT_Credential")] String InstallAccount; +}; + diff --git a/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/readme.md b/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/readme.md new file mode 100644 index 000000000..8fbc9ed53 --- /dev/null +++ b/SharePointDsc/DSCResources/MSFT_SPOAppPrincipalMgmtServiceAppProxy/readme.md @@ -0,0 +1,14 @@ +# Description + +**Type:** Distributed +**Requires CredSSP:** No + +This resource is used to create a SharePoint Online management Application Proxy. +This is used by for example hybrid search. It will identify an instance of the +SPO management apllication proxy through the display name. Currently the +resource will provision the app proxy if it does not yet exist, and will +recreate the proxy if the Online Tenant URI associated to the proxy does not +match the configuration. + +The default value for the Ensure parameter is Present. When not specifying this +parameter, the service application is provisioned. diff --git a/SharePointDsc/Examples/Resources/SPAzureAccessControlServiceAppProxy/1-CreateServiceApplicationProxy.ps1 b/SharePointDsc/Examples/Resources/SPAzureAccessControlServiceAppProxy/1-CreateServiceApplicationProxy.ps1 new file mode 100644 index 000000000..e795828bd --- /dev/null +++ b/SharePointDsc/Examples/Resources/SPAzureAccessControlServiceAppProxy/1-CreateServiceApplicationProxy.ps1 @@ -0,0 +1,61 @@ + +<#PSScriptInfo + +.VERSION 1.0.0 + +.GUID 80d306fa-8bd4-4a8d-9f7a-bf40df95e661 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS + +.LICENSEURI https://github.com/dsccommunity/SharePointDsc/blob/master/LICENSE + +.PROJECTURI https://github.com/dsccommunity/SharePointDsc + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA + +#> + +<# + +.DESCRIPTION +This example shows how to create a new Azure Access Control Service Application Proxy +in the farm connecting to the contoso tenant. + +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $SetupAccount + ) + Import-DscResource -ModuleName SharePointDsc + + node localhost { + SPAzureAccessControlServiceAppProxy SPOACS + { + Name = "SPO ACS" + MetadataServiceEndpointUri = "https://accounts.accesscontrol.windows.net/contoso.onmicrosoft.com/metadata/json/1" + PsDscRunAsCredential = $SetupAccount + } + } +} + diff --git a/SharePointDsc/Examples/Resources/SPOAppPrincipalMgmtServiceAppProxy/1-CreateServiceApplicationProxy.ps1 b/SharePointDsc/Examples/Resources/SPOAppPrincipalMgmtServiceAppProxy/1-CreateServiceApplicationProxy.ps1 new file mode 100644 index 000000000..3633ac13a --- /dev/null +++ b/SharePointDsc/Examples/Resources/SPOAppPrincipalMgmtServiceAppProxy/1-CreateServiceApplicationProxy.ps1 @@ -0,0 +1,59 @@ + +<#PSScriptInfo + +.VERSION 1.0.0 + +.GUID 80d306fa-8bd4-4a8d-9f7a-bf40df95e661 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS + +.LICENSEURI https://github.com/dsccommunity/SharePointDsc/blob/master/LICENSE + +.PROJECTURI https://github.com/dsccommunity/SharePointDsc + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA + +#> + +<# + +.DESCRIPTION +This example shows how to create a new SharePoint Online management Application Proxy +in the farm connecting to the contoso tenant. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $SetupAccount + ) + Import-DscResource -ModuleName SharePointDsc + + node localhost { + SPOAppPrincipalMgmtServiceAppProxy SPOAddInManagementProxy + { + Name = "SPO Add-in Management Proxy" + OnlineTenantUri = "https://contoso.sharepoint.com" + PsDscRunAsCredential = $SetupAccount + } + } +} diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPAzureAccessControlServiceAppProxy.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPAzureAccessControlServiceAppProxy.Tests.ps1 new file mode 100644 index 000000000..030c82c89 --- /dev/null +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPAzureAccessControlServiceAppProxy.Tests.ps1 @@ -0,0 +1,224 @@ +[CmdletBinding()] +param +( + [Parameter()] + [string] + $SharePointCmdletModule = (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\Stubs\SharePoint\15.0.4805.1000\Microsoft.SharePoint.PowerShell.psm1" ` + -Resolve) +) + +$script:DSCModuleName = 'SharePointDsc' +$script:DSCResourceName = 'SPAzureAccessControlServiceAppProxy' +$script:DSCResourceFullName = 'MSFT_' + $script:DSCResourceName +function Invoke-TestSetup +{ + try + { + Import-Module -Name DscResource.Test -Force + + Import-Module -Name (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\UnitTestHelper.psm1" ` + -Resolve) + + $Global:SPDscHelper = New-SPDscUnitTestHelper -SharePointStubModule $SharePointCmdletModule ` + -DscResource $script:DSCResourceName + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + } + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:DSCModuleName ` + -DSCResourceName $script:DSCResourceFullName ` + -ResourceType 'Mof' ` + -TestType 'Unit' +} + +function Invoke-TestCleanup +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} + +Invoke-TestSetup + +try +{ + Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:SPDscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:SPDscHelper.InitializeScript -NoNewScope + + #Initialise tests + $getTypeFullName = "Microsoft.SharePoint.Administration.SPAzureAccessControlServiceApplicationProxy" + + # Mocks for all contexts + Mock -CommandName Remove-SPServiceApplicationProxy -MockWith { } + + # Test contexts + Context -Name "When no service application proxies exist in the current farm and it should" -Fixture { + $testParams = @{ + Name = "Test Proxy" + MetadataServiceEndpointUri = "https://accounts.accesscontrol.windows.net/contoso.onmicrosoft.com/metadata/json/1" + Ensure = "Present" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { return $null } + Mock -CommandName New-SPAzureAccessControlServiceApplicationProxy -MockWith { + $returnVal = @{ + Name = "ServiceApp" + MetadataServiceEndpointUri = [Uri]"https://accounts.accesscontrol.windows.net/contoso.onmicrosoft.com/metadata/json/1" + } + + return $returnVal + } + + It "Should return absent from the get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + Assert-MockCalled Get-SPServiceApplicationProxy + } + + It "Should return false when the test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should create a new service application in the set method" { + Set-TargetResource @testParams + Assert-MockCalled New-SPAzureAccessControlServiceApplicationProxy -ParameterFilter { + $Name -eq $testParams.Name -and + $MetadataServiceEndpointUri -eq $testParams.MetadataServiceEndpointUri + } + } + } + + Context -Name "When service applications exist in the current farm with the same name but metadata service endpoint URI does not match" -Fixture { + $testParams = @{ + Name = "Test Proxy" + MetadataServiceEndpointUri = "https://accounts.accesscontrol.windows.net/contoso.onmicrosoft.com/metadata/json/1" + Ensure = "Present" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { + $spServiceAppProxy = [PSCustomObject]@{ + Name = $testParams.Name + MetadataEndpointUri = [Uri]"https://accounts.accesscontrol.windows.net/litware.onmicrosoft.com/metadata/json/1" + } + $spServiceAppProxy | Add-Member -MemberType ScriptMethod ` + -Name GetType ` + -Value { + return @{ + FullName = $getTypeFullName + } + } -Force + return $spServiceAppProxy + } + Mock -CommandName New-SPAzureAccessControlServiceApplicationProxy -MockWith { return $null } + Mock -CommandName Remove-SPServiceApplicationProxy -MockWith { return $null } + + It "Should return present from the get method" { + $result = Get-TargetResource @testParams + $result.Ensure | Should Be "Present" + $result.MetadataServiceEndpointUri | Should Be "https://accounts.accesscontrol.windows.net/litware.onmicrosoft.com/metadata/json/1" + Assert-MockCalled Get-SPServiceApplicationProxy + } + + It "Should return false when the Test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should recreate the application proxy from the set method" { + Set-TargetResource @testParams + + Assert-MockCalled Get-SPServiceApplicationProxy + Assert-MockCalled Remove-SPServiceApplicationProxy + Assert-MockCalled New-SPAzureAccessControlServiceApplicationProxy -ParameterFilter { + $Name -eq $testParams.Name -and + $MetadataServiceEndpointUri -eq $testParams.MetadataServiceEndpointUri + } + } + } + + Context -Name "When a service application exists and it should, and is also configured correctly" -Fixture { + $testParams = @{ + Name = "Test Proxy" + MetadataServiceEndpointUri = "https://accounts.accesscontrol.windows.net/contoso.onmicrosoft.com/metadata/json/1" + Ensure = "Present" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { + $spServiceAppProxy = [PSCustomObject]@{ + Name = $testParams.Name + MetadataEndpointUri = [Uri]$testParams.MetadataServiceEndpointUri + } + $spServiceAppProxy | Add-Member -MemberType ScriptMethod -Name GetType -Value { + return @{ FullName = $getTypeFullName } + } -Force + return $spServiceAppProxy + } + + It "Should return values from the get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + Assert-MockCalled Get-SPServiceApplicationProxy + } + + It "Should return true when the Test method is called" { + Test-TargetResource @testParams | Should Be $true + } + } + + Context -Name "When the service application proxy exists but it shouldn't" -Fixture { + $testParams = @{ + Name = "Test Proxy" + MetadataServiceEndpointUri = "https://accounts.accesscontrol.windows.net/contoso.onmicrosoft.com/metadata/json/1" + Ensure = "Absent" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { + $spServiceAppProxy = [PSCustomObject]@{ + Name = $testParams.Name + MetadataEndpointUri = [Uri]$testParams.MetadataServiceEndpointUri + } + $spServiceAppProxy | Add-Member -MemberType ScriptMethod -Name GetType -Value { + return @{ FullName = $getTypeFullName } + } -Force + return $spServiceAppProxy + } + + It "Should return present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return false when the Test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should call the remove service application cmdlet in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Remove-SPServiceApplicationProxy + } + } + + Context -Name "When the serivce application doesn't exist and it shouldn't" -Fixture { + $testParams = @{ + Name = "Test Proxy" + MetadataServiceEndpointUri = "https://accounts.accesscontrol.windows.net/contoso.onmicrosoft.com/metadata/json/1" + Ensure = "Absent" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { return $null } + + It "Should return absent from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + } + + It "Should return true when the Test method is called" { + Test-TargetResource @testParams | Should Be $true + } + } + } + } +} +finally +{ + Invoke-TestCleanup +} diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPOAppPrincipalMgmtServiceAppProxy.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPOAppPrincipalMgmtServiceAppProxy.Tests.ps1 new file mode 100644 index 000000000..5f62587c8 --- /dev/null +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPOAppPrincipalMgmtServiceAppProxy.Tests.ps1 @@ -0,0 +1,223 @@ +[CmdletBinding()] +param +( + [Parameter()] + [string] + $SharePointCmdletModule = (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\Stubs\SharePoint\15.0.4805.1000\Microsoft.SharePoint.PowerShell.psm1" ` + -Resolve) +) + +$script:DSCModuleName = 'SharePointDsc' +$script:DSCResourceName = 'SPOAppPrincipalMgmtServiceAppProxy' +$script:DSCResourceFullName = 'MSFT_' + $script:DSCResourceName +function Invoke-TestSetup +{ + try + { + Import-Module -Name DscResource.Test -Force + + Import-Module -Name (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\UnitTestHelper.psm1" ` + -Resolve) + + $Global:SPDscHelper = New-SPDscUnitTestHelper -SharePointStubModule $SharePointCmdletModule ` + -DscResource $script:DSCResourceName + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + } + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:DSCModuleName ` + -DSCResourceName $script:DSCResourceFullName ` + -ResourceType 'Mof' ` + -TestType 'Unit' +} + +function Invoke-TestCleanup +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} + +Invoke-TestSetup + +try +{ + Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:SPDscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:SPDscHelper.InitializeScript -NoNewScope + + #Initialise tests + $getTypeFullName = "Microsoft.SharePoint.Administration.SPOnlineApplicationPrincipalManagementServiceApplicationProxy" + + # Mocks for all contexts + Mock -CommandName Remove-SPServiceApplicationProxy -MockWith { } + + # Test contexts + Context -Name "When no service application proxies exist in the current farm and it should" -Fixture { + $testParams = @{ + Name = "Test Proxy" + OnlineTenantUri = "https://contoso.sharepoint.com" + Ensure = "Present" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { return $null } + Mock -CommandName New-SPOnlineApplicationPrincipalManagementServiceApplicationProxy -MockWith { + $returnVal = @{ + Name = "ServiceApp" + OnlineTenantUri = [Uri]"https://contoso.sharepoint.com" + } + return $returnVal + } + + It "Should return absent from the get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + Assert-MockCalled Get-SPServiceApplicationProxy + } + + It "Should return false when the test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should create a new service application in the set method" { + Set-TargetResource @testParams + Assert-MockCalled New-SPOnlineApplicationPrincipalManagementServiceApplicationProxy -ParameterFilter { + $Name -eq $testParams.Name -and + $OnlineTenantUri -eq $testParams.OnlineTenantUri + } + } + } + + Context -Name "When service applications exist in the current farm with the same name but metadata service endpoint URI does not match" -Fixture { + $testParams = @{ + Name = "Test Proxy" + OnlineTenantUri = "https://contoso.sharepoint.com" + Ensure = "Present" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { + $spServiceAppProxy = [PSCustomObject]@{ + Name = $testParams.Name + OnlineTenantUri = [Uri]"https://litware.sharepoint.com" + } + $spServiceAppProxy | Add-Member -MemberType ScriptMethod ` + -Name GetType ` + -Value { + return @{ + FullName = $getTypeFullName + } + } -Force + return $spServiceAppProxy + } + Mock -CommandName New-SPOnlineApplicationPrincipalManagementServiceApplicationProxy -MockWith { return $null } + Mock -CommandName Remove-SPServiceApplicationProxy -MockWith { return $null } + + It "Should return present from the get method" { + $result = Get-TargetResource @testParams + $result.Ensure | Should Be "Present" + $result.OnlineTenantUri | Should Be "https://litware.sharepoint.com" + Assert-MockCalled Get-SPServiceApplicationProxy + } + + It "Should return false when the Test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should recreate the application proxy from the set method" { + Set-TargetResource @testParams + + Assert-MockCalled Get-SPServiceApplicationProxy + Assert-MockCalled Remove-SPServiceApplicationProxy + Assert-MockCalled New-SPOnlineApplicationPrincipalManagementServiceApplicationProxy -ParameterFilter { + $Name -eq $testParams.Name -and + $OnlineTenantUri -eq $testParams.OnlineTenantUri + } + } + } + + Context -Name "When a service application exists and it should, and is also configured correctly" -Fixture { + $testParams = @{ + Name = "Test Proxy" + OnlineTenantUri = "https://contoso.sharepoint.com" + Ensure = "Present" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { + $spServiceAppProxy = [PSCustomObject]@{ + Name = $testParams.Name + OnlineTenantUri = [Uri]$testParams.OnlineTenantUri + } + $spServiceAppProxy | Add-Member -MemberType ScriptMethod -Name GetType -Value { + return @{ FullName = $getTypeFullName } + } -Force + return $spServiceAppProxy + } + + It "Should return values from the get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + Assert-MockCalled Get-SPServiceApplicationProxy + } + + It "Should return true when the Test method is called" { + Test-TargetResource @testParams | Should Be $true + } + } + + Context -Name "When the service application proxy exists but it shouldn't" -Fixture { + $testParams = @{ + Name = "Test Proxy" + OnlineTenantUri = "https://contoso.sharepoint.com" + Ensure = "Absent" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { + $spServiceAppProxy = [PSCustomObject]@{ + Name = $testParams.Name + OnlineTenantUri = [Uri]$testParams.OnlineTenantUri + } + $spServiceAppProxy | Add-Member -MemberType ScriptMethod -Name GetType -Value { + return @{ FullName = $getTypeFullName } + } -Force + return $spServiceAppProxy + } + + It "Should return present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return false when the Test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should call the remove service application cmdlet in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Remove-SPServiceApplicationProxy + } + } + + Context -Name "When the serivce application doesn't exist and it shouldn't" -Fixture { + $testParams = @{ + Name = "Test Proxy" + OnlineTenantUri = "https://contoso.sharepoint.com" + Ensure = "Absent" + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { return $null } + + It "Should return absent from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + } + + It "Should return true when the Test method is called" { + Test-TargetResource @testParams | Should Be $true + } + } + } + } +} +finally +{ + Invoke-TestCleanup +}