Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- `SqlPermission`
- Refactored to use the new object-based server permission commands
(`Grant-SqlDscServerPermission`, `Deny-SqlDscServerPermission`,
`Revoke-SqlDscServerPermission`, and `Get-SqlDscServerPermission`)
instead of the deprecated `Set-SqlDscServerPermission` command
([issue #2159](https://github.com/dsccommunity/SqlServerDsc/issues/2159)).
- Updated comment-based help `.INPUTS` and `.OUTPUTS` sections across all public
commands and private functions to comply with DSC community style guidelines
([issue #2103](https://github.com/dsccommunity/SqlServerDsc/issues/2103)).
Expand Down
123 changes: 90 additions & 33 deletions source/Classes/020.SqlPermission.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,18 @@ class SqlPermission : SqlResourceBase
New-InvalidOperationException -Message $missingPrincipalMessage
}

# Get the principal object (Login or ServerRole)
$principalObject = $null

if ($isLogin)
{
$principalObject = $serverObject | Get-SqlDscLogin -Name $this.Name -ErrorAction 'Stop'
}
else
{
$principalObject = $serverObject | Get-SqlDscRole -Name $this.Name -ErrorAction 'Stop'
}

# This holds each state and their permissions to be revoked.
[ServerPermission[]] $permissionsToRevoke = @()
[ServerPermission[]] $permissionsToGrantOrDeny = @()
Expand Down Expand Up @@ -455,32 +467,41 @@ class SqlPermission : SqlResourceBase
#>
foreach ($currentStateToRevoke in $permissionsToRevoke)
{
$revokePermissionSet = $currentStateToRevoke | ConvertFrom-SqlDscServerPermission

$setSqlDscServerPermissionParameters = @{
ServerObject = $serverObject
Name = $this.Name
Permission = $revokePermissionSet
State = 'Revoke'
Force = $true
}
# Convert ServerPermission to array of SqlServerPermission enum values
$permissionsToRevokeArray = $currentStateToRevoke.Permission

if ($currentStateToRevoke.State -eq 'GrantWithGrant')
# Only revoke if there are permissions to revoke
if ($permissionsToRevokeArray.Count -gt 0)
{
$setSqlDscServerPermissionParameters.WithGrant = $true
}
$revokeSqlDscServerPermissionParameters = @{
Permission = $permissionsToRevokeArray
Force = $true
}

try
{
Set-SqlDscServerPermission @setSqlDscServerPermissionParameters
}
catch
{
$errorMessage = $this.localizedData.FailedToRevokePermissionFromCurrentState -f @(
$this.Name
)
if ($currentStateToRevoke.State -eq 'GrantWithGrant')
{
$revokeSqlDscServerPermissionParameters.WithGrant = $true
}

try
{
if ($isLogin)
{
Revoke-SqlDscServerPermission -Login $principalObject @revokeSqlDscServerPermissionParameters
}
else
{
Revoke-SqlDscServerPermission -ServerRole $principalObject @revokeSqlDscServerPermissionParameters
}
}
catch
{
$errorMessage = $this.localizedData.FailedToRevokePermissionFromCurrentState -f @(
$this.Name
)

New-InvalidOperationException -Message $errorMessage -ErrorRecord $_
New-InvalidOperationException -Message $errorMessage -ErrorRecord $_
}
}
}
}
Expand All @@ -496,27 +517,63 @@ class SqlPermission : SqlResourceBase
# If there is not an empty array, change permissions.
if (-not [System.String]::IsNullOrEmpty($currentDesiredPermissionState.Permission))
{
$permissionSet = $currentDesiredPermissionState | ConvertFrom-SqlDscServerPermission

$setSqlDscServerPermissionParameters = @{
ServerObject = $serverObject
Name = $this.Name
Permission = $permissionSet
Force = $true
}
# Convert ServerPermission to array of SqlServerPermission enum values
$permissionsArray = $currentDesiredPermissionState.Permission

try
{
switch ($currentDesiredPermissionState.State)
{
'Grant'
{
$grantParameters = @{
Permission = $permissionsArray
Force = $true
}

if ($isLogin)
{
Grant-SqlDscServerPermission -Login $principalObject @grantParameters
}
else
{
Grant-SqlDscServerPermission -ServerRole $principalObject @grantParameters
}
}

'GrantWithGrant'
{
Set-SqlDscServerPermission @setSqlDscServerPermissionParameters -State 'Grant' -WithGrant
$grantParameters = @{
Permission = $permissionsArray
WithGrant = $true
Force = $true
}

if ($isLogin)
{
Grant-SqlDscServerPermission -Login $principalObject @grantParameters
}
else
{
Grant-SqlDscServerPermission -ServerRole $principalObject @grantParameters
}
}

default
'Deny'
{
Set-SqlDscServerPermission @setSqlDscServerPermissionParameters -State $currentDesiredPermissionState.State
$denyParameters = @{
Permission = $permissionsArray
Force = $true
}

if ($isLogin)
{
Deny-SqlDscServerPermission -Login $principalObject @denyParameters
}
else
{
Deny-SqlDscServerPermission -ServerRole $principalObject @denyParameters
}
}
}
}
Expand Down
116 changes: 89 additions & 27 deletions tests/Unit/Classes/SqlPermission.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,16 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
return $true
}

Mock -CommandName Set-SqlDscServerPermission
Mock -CommandName Get-SqlDscLogin -MockWith {
return New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Login' -ArgumentList @(
(New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'),
'MockUserName'
)
}

Mock -CommandName Grant-SqlDscServerPermission
Mock -CommandName Deny-SqlDscServerPermission
Mock -CommandName Revoke-SqlDscServerPermission
}

It 'Should call the correct mock with the correct parameter values' {
Expand All @@ -1171,13 +1180,13 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
}

# Grants
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Grant' -and $Permission.ConnectSql -eq $true
Should -Invoke -CommandName Grant-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'ConnectSql' -and -not $PSBoundParameters.ContainsKey('WithGrant')
} -Exactly -Times 1 -Scope It

# GrantWithGrants
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Grant' -and $Permission.AlterAnyEndpoint -eq $true
Should -Invoke -CommandName Grant-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'AlterAnyEndpoint' -and $WithGrant -eq $true
} -Exactly -Times 1 -Scope It
}
}
Expand Down Expand Up @@ -1234,7 +1243,16 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
return $true
}

Mock -CommandName Set-SqlDscServerPermission
Mock -CommandName Get-SqlDscLogin -MockWith {
return New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Login' -ArgumentList @(
(New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'),
'MockUserName'
)
}

Mock -CommandName Grant-SqlDscServerPermission
Mock -CommandName Deny-SqlDscServerPermission
Mock -CommandName Revoke-SqlDscServerPermission
}

It 'Should call the correct mock with the correct parameter values' {
Expand All @@ -1258,23 +1276,23 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
}

# Revoking Grants
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Revoke' -and $Permission.AlterAnyAvailabilityGroup -eq $true -and $Permission.ViewServerState -eq $true
Should -Invoke -CommandName Revoke-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'AlterAnyAvailabilityGroup' -and $Permission -contains 'ViewServerState' -and -not $PSBoundParameters.ContainsKey('WithGrant')
} -Exactly -Times 1 -Scope It

# Revoking GrantWithGrants
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Revoke' -and $Permission.ControlServer -eq $true
Should -Invoke -CommandName Revoke-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'ControlServer' -and $WithGrant -eq $true
} -Exactly -Times 1 -Scope It

# Revoking Denies
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Revoke' -and $Permission.CreateEndpoint -eq $true
Should -Invoke -CommandName Revoke-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'CreateEndpoint' -and -not $PSBoundParameters.ContainsKey('WithGrant')
} -Exactly -Times 1 -Scope It

# Adding new Grant
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Grant' -and $Permission.ConnectSql -eq $true
Should -Invoke -CommandName Grant-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'ConnectSql' -and -not $PSBoundParameters.ContainsKey('WithGrant')
} -Exactly -Times 1 -Scope It
}
}
Expand Down Expand Up @@ -1333,7 +1351,16 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
return $true
}

Mock -CommandName Set-SqlDscServerPermission
Mock -CommandName Get-SqlDscLogin -MockWith {
return New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Login' -ArgumentList @(
(New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'),
'MockUserName'
)
}

Mock -CommandName Grant-SqlDscServerPermission
Mock -CommandName Deny-SqlDscServerPermission
Mock -CommandName Revoke-SqlDscServerPermission
}

It 'Should call the correct mock with the correct parameter values' {
Expand All @@ -1357,13 +1384,13 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
}

# Grants
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Grant' -and $Permission.ConnectSql -eq $true
Should -Invoke -CommandName Grant-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'ConnectSql' -and -not $PSBoundParameters.ContainsKey('WithGrant')
} -Exactly -Times 1 -Scope It

# GrantWithGrants
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Grant' -and $Permission.AlterAnyEndpoint -eq $true
Should -Invoke -CommandName Grant-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'AlterAnyEndpoint' -and $WithGrant -eq $true
} -Exactly -Times 1 -Scope It
}
}
Expand Down Expand Up @@ -1422,7 +1449,16 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
return $true
}

Mock -CommandName Set-SqlDscServerPermission
Mock -CommandName Get-SqlDscLogin -MockWith {
return New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Login' -ArgumentList @(
(New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'),
'MockUserName'
)
}

Mock -CommandName Grant-SqlDscServerPermission
Mock -CommandName Deny-SqlDscServerPermission
Mock -CommandName Revoke-SqlDscServerPermission
}

It 'Should call the correct mock with the correct parameter values' {
Expand All @@ -1446,19 +1482,19 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
}

# Revoking Grants
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Revoke' -and $Permission.ConnectSql -eq $true
Should -Invoke -CommandName Revoke-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'ConnectSql' -and -not $PSBoundParameters.ContainsKey('WithGrant')
} -Exactly -Times 1 -Scope It

# Revoking GrantWithGrants
Should -Invoke -CommandName Set-SqlDscServerPermission -ParameterFilter {
$State -eq 'Revoke' -and $Permission.AlterAnyEndpoint -eq $true
Should -Invoke -CommandName Revoke-SqlDscServerPermission -ParameterFilter {
$Permission -contains 'AlterAnyEndpoint' -and $WithGrant -eq $true
} -Exactly -Times 1 -Scope It
}
}
}

Context 'When Set-SqlDscServerPermission fails to change permission' {
Context 'When Grant/Deny/Revoke commands fail to change permission' {
Context 'When granting permissions' {
BeforeAll {
InModuleScope -ScriptBlock {
Expand Down Expand Up @@ -1511,7 +1547,20 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
return $true
}

Mock -CommandName Set-SqlDscServerPermission -MockWith {
Mock -CommandName Get-SqlDscLogin -MockWith {
return New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Login' -ArgumentList @(
(New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'),
'MockUserName'
)
}

Mock -CommandName Grant-SqlDscServerPermission -MockWith {
throw 'Mocked error'
}
Mock -CommandName Deny-SqlDscServerPermission -MockWith {
throw 'Mocked error'
}
Mock -CommandName Revoke-SqlDscServerPermission -MockWith {
throw 'Mocked error'
}
}
Expand Down Expand Up @@ -1602,7 +1651,20 @@ Describe 'SqlPermission\Modify()' -Tag 'Modify' {
return $true
}

Mock -CommandName Set-SqlDscServerPermission -MockWith {
Mock -CommandName Get-SqlDscLogin -MockWith {
return New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Login' -ArgumentList @(
(New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'),
'MockUserName'
)
}

Mock -CommandName Grant-SqlDscServerPermission -MockWith {
throw 'Mocked error'
}
Mock -CommandName Deny-SqlDscServerPermission -MockWith {
throw 'Mocked error'
}
Mock -CommandName Revoke-SqlDscServerPermission -MockWith {
throw 'Mocked error'
}
}
Expand Down