Merge pull request #386 from dmilov/topic/dmilov/SsoAdminModule
PowerShell Module for managing VMware vSphere SSO Admin functionality
This commit is contained in:
30
Modules/VMware.vSphere.SsoAdmin/README.md
Normal file
30
Modules/VMware.vSphere.SsoAdmin/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# PowerCLI Example module for managing vSphere SSO Admin
|
||||
This module is combination of .NET binary libraries for accessing vSphere SSO Admin API and PowerShell advanced functions exposing cmdlet-like interface to the SSO Admin features.<br/>
|
||||
<br/>
|
||||
The module supports PowerShell 5.1 and PowerShell 7.0 and above.<br/>
|
||||
|
||||
# Using the module
|
||||
The module can be used without the '/src' directory. The '/src' directory contains the source code of the module.<br/>
|
||||
|
||||
This module depends on PowerCLI 'VMware.VimAutomation.Common', Version 12.0 module<br/>
|
||||
|
||||
# Using the source code
|
||||
## '/src' directory
|
||||
This directory contains the .NET binaries sources code and Pester integration tests that cover both the binaries and the module advanced functions functionality.<br/>
|
||||
|
||||
## Required build tools
|
||||
- PowerShell 7.0<br/>
|
||||
- dotnet sdk<br/>
|
||||
|
||||
## Required test tools
|
||||
- PowerShell 7.0
|
||||
- PowerCLI 12.0<br/>
|
||||
- Pester 4.8.1<br/>
|
||||
|
||||
## '/src/build.ps1' script
|
||||
The script builds the binaries and publishes them to the 'net45' and 'netcoreapp2.0' directories of the module.<br/>
|
||||
|
||||
It has also the option to run module Pester tests. The optional parameters for VC server and credentials has to be specified in order the script to run the tests. Tests run in separate PowreShell process because PowerShell has to load the module binaries which are build output.<br/>
|
||||
|
||||
## '/src/test/RunTests.ps1' script
|
||||
This script can be used to run the tests<br/>
|
||||
47
Modules/VMware.vSphere.SsoAdmin/VMware.vSphere.SsoAdmin.psd1
Normal file
47
Modules/VMware.vSphere.SsoAdmin/VMware.vSphere.SsoAdmin.psd1
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# Module manifest for module 'VMware.vSphere.SsoAdmin'
|
||||
#
|
||||
# Generated by: dmilov@vmware.com
|
||||
#
|
||||
# Generated on: 9/25/20
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest
|
||||
RootModule = 'VMware.vSphere.SsoAdmin.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0.0'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = 'b3e25326-e809-4d68-a252-ca5fcaf1eb8b'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Dimitar Milov'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware, Inc.'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = 'Copyright (c) VMware, Inc. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'PowerShell Module for Managing VMware vSphere SSO Admin functionality.'
|
||||
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
RequiredModules = @(
|
||||
@{"ModuleName"="VMware.VimAutomation.Common";"ModuleVersion"="12.0.0.15939652"}
|
||||
)
|
||||
|
||||
# Functions to export from this module
|
||||
FunctionsToExport = @('Connect-SsoAdminServer', 'Disconnect-SsoAdminServer', 'New-SsoPersonUser', 'Get-SsoPersonUser', 'Set-SsoPersonUser', 'Remove-SsoPersonUser', 'Get-SsoGroup', 'Get-SsoPasswordPolicy', 'Set-SsoPasswordPolicy', 'Get-SsoLockoutPolicy', 'Set-SsoLockoutPolicy', 'Get-SsoTokenLifetime', 'Set-SsoTokenLifetime', 'Add-ActiveDirectoryIdentitySource')
|
||||
|
||||
# Cmdlets to export from this module
|
||||
CmdletsToExport = @()
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = ''
|
||||
|
||||
# Aliases to export from this module
|
||||
AliasesToExport = '*'
|
||||
}
|
||||
1369
Modules/VMware.vSphere.SsoAdmin/VMware.vSphere.SsoAdmin.psm1
Normal file
1369
Modules/VMware.vSphere.SsoAdmin/VMware.vSphere.SsoAdmin.psm1
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,86 @@
|
||||
#
|
||||
# Module manifest for module 'VMware.vSphere.SsoAdmin'
|
||||
#
|
||||
# Generated by: dmilov@vmware.com
|
||||
#
|
||||
# Generated on: 9/25/20
|
||||
|
||||
@{
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0.0'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = 'dd2b1928-e8ee-4c3a-a364-1caec6d3bd58'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Dimitar Milov'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware, Inc.'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = 'Copyright (c) VMware, Inc. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'PowerShell Module for Managing VMware vSphere SSO Admin functionality.'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
# Name of the Windows PowerShell host required by this module
|
||||
PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the Windows PowerShell host required by this module
|
||||
PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of the .NET Framework required by this module
|
||||
DotNetFrameworkVersion = '4.5'
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module
|
||||
CLRVersion = '4.0'
|
||||
|
||||
# Processor architecture (None, X86, Amd64, IA64) required by this module
|
||||
ProcessorArchitecture = ''
|
||||
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
RequiredAssemblies = @(
|
||||
'VMware.vSphere.SsoAdmin.Utils.dll',
|
||||
'VMware.vSphere.SsoAdminClient.dll',
|
||||
'VMware.vSphere.LsClient.dll'
|
||||
)
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
#FormatsToProcess = 'VMware.vSphere.SsoAdmin.Format.ps1xml'
|
||||
|
||||
# Modules to import as nested modules of the module specified in ModuleToProcess
|
||||
#NestedModules= @()
|
||||
|
||||
# Functions to export from this module
|
||||
FunctionsToExport = '*'
|
||||
|
||||
# Cmdlets to export from this module
|
||||
CmdletsToExport = '*'
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module
|
||||
AliasesToExport = '*'
|
||||
|
||||
# List of all modules packaged with this module
|
||||
ModuleList = @()
|
||||
|
||||
# List of all files packaged with this module
|
||||
FileList = ''
|
||||
|
||||
# Private data to pass to the module specified in ModuleToProcess
|
||||
PrivateData = ''
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,83 @@
|
||||
#
|
||||
# Module manifest for module 'VMware.vSphere.SsoAdmin'
|
||||
#
|
||||
# Generated by: dmilov@vmware.com
|
||||
#
|
||||
# Generated on: 9/25/20
|
||||
|
||||
@{
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0.0'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '29f1ed8b-311a-4ea1-80a6-0f3ec56e8259'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Dimitar Milov'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'VMware, Inc.'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = 'Copyright (c) VMware, Inc. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'PowerShell Module for Managing VMware vSphere SSO Admin functionality.'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
PowerShellVersion = '6.0.1'
|
||||
|
||||
# Specifies the compatible PSEditions of the module.
|
||||
CompatiblePSEditions = @('Core')
|
||||
|
||||
# Name of the Windows PowerShell host required by this module
|
||||
PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the Windows PowerShell host required by this module
|
||||
PowerShellHostVersion = ''
|
||||
|
||||
# Processor architecture (None, X86, Amd64, IA64) required by this module
|
||||
ProcessorArchitecture = ''
|
||||
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
RequiredAssemblies = @(
|
||||
'VMware.vSphere.SsoAdmin.Utils.dll',
|
||||
'VMware.vSphere.SsoAdminClient.dll',
|
||||
'VMware.vSphere.LsClient.dll'
|
||||
)
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
#FormatsToProcess = 'VMware.vSphere.SsoAdmin.Format.ps1xml'
|
||||
|
||||
# Modules to import as nested modules of the module specified in ModuleToProcess
|
||||
#NestedModules= @()
|
||||
|
||||
# Functions to export from this module
|
||||
FunctionsToExport = '*'
|
||||
|
||||
# Cmdlets to export from this module
|
||||
CmdletsToExport = '*'
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module
|
||||
AliasesToExport = '*'
|
||||
|
||||
# List of all modules packaged with this module
|
||||
ModuleList = @()
|
||||
|
||||
# List of all files packaged with this module
|
||||
FileList = ''
|
||||
|
||||
# Private data to pass to the module specified in ModuleToProcess
|
||||
PrivateData = ''
|
||||
|
||||
}
|
||||
Binary file not shown.
3
Modules/VMware.vSphere.SsoAdmin/src/.gitignore
vendored
Normal file
3
Modules/VMware.vSphere.SsoAdmin/src/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
**/.vs
|
||||
**/bin
|
||||
**/obj
|
||||
@@ -0,0 +1,5 @@
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="LocalPackages" value="packages" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"ProviderId": "Microsoft.VisualStudio.ConnectedService.Wcf",
|
||||
"Version": "15.0.20628.921",
|
||||
"ExtendedData": {
|
||||
"Uri": "https://10.23.80.205/lookupservice/wsdl/lookup.wsdl",
|
||||
"Namespace": "LookupServiceReference",
|
||||
"SelectedAccessLevelForGeneratedClass": "Public",
|
||||
"GenerateMessageContract": false,
|
||||
"ReuseTypesinReferencedAssemblies": true,
|
||||
"ReuseTypesinAllReferencedAssemblies": true,
|
||||
"CollectionTypeReference": {
|
||||
"Item1": "System.Array",
|
||||
"Item2": "System.Runtime.dll"
|
||||
},
|
||||
"DictionaryCollectionTypeReference": {
|
||||
"Item1": "System.Collections.Generic.Dictionary`2",
|
||||
"Item2": "System.Collections.dll"
|
||||
},
|
||||
"CheckedReferencedAssemblies": [],
|
||||
"InstanceId": null,
|
||||
"Name": "LookupServiceReference",
|
||||
"Metadata": {}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Selectors;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Security;
|
||||
using System.Text;
|
||||
using LookupServiceReference;
|
||||
|
||||
namespace VMware.vSphere.LsClient
|
||||
{
|
||||
public class LookupServiceClient {
|
||||
private const int WEB_OPERATION_TIMEOUT_SECONDS = 30;
|
||||
private LsPortTypeClient _lsClient;
|
||||
|
||||
private static readonly ManagedObjectReference RootMoRef = new ManagedObjectReference
|
||||
{
|
||||
type = "LookupServiceInstance",
|
||||
Value = "ServiceInstance"
|
||||
};
|
||||
|
||||
public LookupServiceClient(string hostname, X509CertificateValidator serverCertificateValidator) {
|
||||
var lsUri = $"https://{hostname}/lookupservice/sdk";
|
||||
|
||||
_lsClient = new LsPortTypeClient(GetBinding(), new EndpointAddress(new Uri(lsUri)));
|
||||
|
||||
var serverAuthentication = GetServerAuthentication(serverCertificateValidator);
|
||||
|
||||
if (serverAuthentication != null)
|
||||
{
|
||||
_lsClient
|
||||
.ChannelFactory
|
||||
.Credentials
|
||||
.ServiceCertificate
|
||||
.SslCertificateAuthentication = serverAuthentication;
|
||||
}
|
||||
}
|
||||
|
||||
#region Private Helpers
|
||||
private X509ServiceCertificateAuthentication GetServerAuthentication(X509CertificateValidator serverCertificateValidator)
|
||||
{
|
||||
if (serverCertificateValidator != null) {
|
||||
return new X509ServiceCertificateAuthentication {
|
||||
CertificateValidationMode = X509CertificateValidationMode.Custom,
|
||||
CustomCertificateValidator = serverCertificateValidator
|
||||
};
|
||||
}
|
||||
|
||||
// Default .NET behavior for TLS certificate validation
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MessageEncodingBindingElement GetWcfEncoding()
|
||||
{
|
||||
return new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
|
||||
}
|
||||
|
||||
private static HttpsTransportBindingElement GetWcfTransport(bool useSystemProxy)
|
||||
{
|
||||
HttpsTransportBindingElement transport = new HttpsTransportBindingElement
|
||||
{
|
||||
RequireClientCertificate = false
|
||||
};
|
||||
|
||||
transport.UseDefaultWebProxy = useSystemProxy;
|
||||
transport.MaxBufferSize = 2147483647;
|
||||
transport.MaxReceivedMessageSize = 2147483647;
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
||||
private static Binding GetBinding() {
|
||||
var binding = new CustomBinding(GetWcfEncoding(), GetWcfTransport(true));
|
||||
|
||||
var timeout = TimeSpan.FromSeconds(WEB_OPERATION_TIMEOUT_SECONDS);
|
||||
binding.CloseTimeout = timeout;
|
||||
binding.OpenTimeout = timeout;
|
||||
binding.ReceiveTimeout = timeout;
|
||||
binding.SendTimeout = timeout;
|
||||
|
||||
return binding;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Uri GetSsoAdminEndpointUri() {
|
||||
var product = "com.vmware.cis";
|
||||
var endpointType = "com.vmware.cis.cs.identity.admin";
|
||||
var type = "sso:admin";
|
||||
return FindServiceEndpoint(product, type, endpointType);
|
||||
}
|
||||
|
||||
public Uri GetStsEndpointUri() {
|
||||
var product = "com.vmware.cis";
|
||||
var type = "cs.identity";
|
||||
var endpointType = "com.vmware.cis.cs.identity.sso";
|
||||
return FindServiceEndpoint(product, type, endpointType);
|
||||
}
|
||||
|
||||
private Uri FindServiceEndpoint(string product, string type, string endpointType) {
|
||||
Uri result = null;
|
||||
|
||||
var svcContent = _lsClient.RetrieveServiceContentAsync(RootMoRef).Result;
|
||||
var filterCriteria = new LookupServiceRegistrationFilter() {
|
||||
searchAllSsoDomains = true,
|
||||
serviceType = new LookupServiceRegistrationServiceType {
|
||||
product = product,
|
||||
type = type
|
||||
}
|
||||
};
|
||||
|
||||
var lsRegInfo = _lsClient.
|
||||
ListAsync(svcContent.serviceRegistration, filterCriteria)
|
||||
.Result?
|
||||
.returnval?
|
||||
.FirstOrDefault();
|
||||
if (lsRegInfo != null) {
|
||||
var registrationEndpooint = lsRegInfo.
|
||||
serviceEndpoints?.
|
||||
Where(a => a.endpointType.type == endpointType)?.
|
||||
FirstOrDefault<LookupServiceRegistrationEndpoint>();
|
||||
if (registrationEndpooint != null) {
|
||||
result = new Uri(registrationEndpooint.url);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>VMware.vSphere.LsClient</RootNamespace>
|
||||
<AssemblyName>VMware.vSphere.LsClient</AssemblyName>
|
||||
<Description>vSphere Lookup Service API client.</Description>
|
||||
<TargetFrameworks>net45;netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
|
||||
<Reference Include="System.IdentityModel" />
|
||||
<PackageReference Include="System.ServiceModel.Primitives" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Duplex" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Http" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Security" Version="4.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
|
||||
<PackageReference Include="VMware.System.Private.ServiceModel" Version="4.4.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<WCFMetadata Include="Connected Services" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30503.244
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VMware.vSphere.SsoAdminClient", "VMware.vSphere.SsoAdminClient\VMware.vSphere.SsoAdminClient.csproj", "{BD48E0DD-4048-48FD-B0BE-560E2417A2CC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VMware.vSphere.LsClient", "VMware.vSphere.LsClient\VMware.vSphere.LsClient.csproj", "{EEC4C335-3E6C-4FA5-84CD-CBADCD720F35}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VMware.vSphere.SsoAdmin.Utils", "VMware.vSphere.SsoAdmin.Utils\VMware.vSphere.SsoAdmin.Utils.csproj", "{1523743E-C01E-4D37-845F-0BB8DAF9EE7E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMware.vSphere.SsoAdminClient.Tests", "VMware.vSphere.SsoAdminClient.Tests\VMware.vSphere.SsoAdminClient.Tests.csproj", "{90E6C4A6-FDB4-43FC-B156-ADBCF2B85CCE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{BD48E0DD-4048-48FD-B0BE-560E2417A2CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BD48E0DD-4048-48FD-B0BE-560E2417A2CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BD48E0DD-4048-48FD-B0BE-560E2417A2CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BD48E0DD-4048-48FD-B0BE-560E2417A2CC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EEC4C335-3E6C-4FA5-84CD-CBADCD720F35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EEC4C335-3E6C-4FA5-84CD-CBADCD720F35}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EEC4C335-3E6C-4FA5-84CD-CBADCD720F35}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EEC4C335-3E6C-4FA5-84CD-CBADCD720F35}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1523743E-C01E-4D37-845F-0BB8DAF9EE7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1523743E-C01E-4D37-845F-0BB8DAF9EE7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1523743E-C01E-4D37-845F-0BB8DAF9EE7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1523743E-C01E-4D37-845F-0BB8DAF9EE7E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{90E6C4A6-FDB4-43FC-B156-ADBCF2B85CCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{90E6C4A6-FDB4-43FC-B156-ADBCF2B85CCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{90E6C4A6-FDB4-43FC-B156-ADBCF2B85CCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{90E6C4A6-FDB4-43FC-B156-ADBCF2B85CCE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9A376526-4487-43FF-A527-E34AD4764F12}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,20 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
|
||||
using System;
|
||||
using System.IdentityModel.Selectors;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace VMware.vSphere.SsoAdmin.Utils
|
||||
{
|
||||
public class AcceptAllX509CertificateValidator : X509CertificateValidator
|
||||
{
|
||||
public override void Validate(X509Certificate2 certificate) {
|
||||
// Check that there is a certificate.
|
||||
if (certificate == null) {
|
||||
throw new ArgumentNullException(nameof(certificate));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VMware.vSphere.SsoAdmin.Utils
|
||||
{
|
||||
public class StirngToSecureStringArgumentTransformationAttribute : ArgumentTransformationAttribute
|
||||
{
|
||||
private static class SecureStringConverter
|
||||
{
|
||||
public static SecureString ToSecureString(string value) {
|
||||
var result = new SecureString();
|
||||
|
||||
foreach (var c in value.ToCharArray()) {
|
||||
result.AppendChar(c);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public override object Transform(EngineIntrinsics engineIntrinsics, object inputData) {
|
||||
object result = inputData;
|
||||
if (inputData is string s) {
|
||||
result = SecureStringConverter.ToSecureString(s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>VMware.vSphere.SsoAdmin.Utils</RootNamespace>
|
||||
<AssemblyName>VMware.vSphere.SsoAdmin.Utils</AssemblyName>
|
||||
<Description>vSphere Lookup SsoAdmin utility types.</Description>
|
||||
<TargetFrameworks>net45;netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
|
||||
<Reference Include="System.IdentityModel" />
|
||||
<PackageReference Include="System.ServiceModel.Primitives" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Duplex" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Http" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Security" Version="4.4.0" />
|
||||
<PackageReference Include="Microsoft.PowerShell.5.ReferenceAssemblies" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
|
||||
<PackageReference Include="Microsoft.WSMan.Runtime" Version="6.1.0" />
|
||||
<PackageReference Include="VMware.System.Private.ServiceModel" Version="4.4.4" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,268 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using VMware.vSphere.SsoAdmin.Utils;
|
||||
using VMware.vSphere.SsoAdminClient.DataTypes;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient.Tests
|
||||
{
|
||||
public class Tests
|
||||
{
|
||||
private string _vc = "<vc>";
|
||||
private string _user = "<user>";
|
||||
private string _rawPassword = "<password>";
|
||||
private SecureString _password;
|
||||
[SetUp]
|
||||
public void Setup() {
|
||||
_password = new SecureString();
|
||||
foreach (char c in _rawPassword) {
|
||||
_password.AppendChar(c);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddRemoveLocalUser() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
var expectedUserName = "test-user2";
|
||||
var expectedPassword = "te$tPa$sW0rd";
|
||||
var expectedDescription = "test-description";
|
||||
var expectedEmail = "testuse@testdomain.loc";
|
||||
var expectedFirstName = "Test";
|
||||
var expectedLastName = "User";
|
||||
|
||||
// Act Create User
|
||||
var actual = ssoAdminClient.CreateLocalUser(
|
||||
expectedUserName,
|
||||
expectedPassword,
|
||||
expectedDescription,
|
||||
expectedEmail,
|
||||
expectedFirstName,
|
||||
expectedLastName);
|
||||
|
||||
// Assert Created User
|
||||
Assert.AreEqual(expectedUserName, actual.Name);
|
||||
Assert.AreEqual(expectedDescription, actual.Description);
|
||||
Assert.AreEqual(expectedEmail, actual.EmailAddress);
|
||||
Assert.AreEqual(expectedFirstName, actual.FirstName);
|
||||
Assert.AreEqual(expectedLastName, actual.LastName);
|
||||
|
||||
// Act Delete User
|
||||
ssoAdminClient.DeleteLocalUser(
|
||||
actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAllLocalOsUsers() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
|
||||
// Act
|
||||
var actual = ssoAdminClient.GetLocalUsers("", "localos").ToArray();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(actual);
|
||||
Assert.Greater(actual.Length, 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetRootLocalOsUsers() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
|
||||
// Act
|
||||
var actual = ssoAdminClient.GetLocalUsers("root", "localos").ToArray();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(actual);
|
||||
Assert.AreEqual(1, actual.Length);
|
||||
Assert.AreEqual("root", actual[0].Name);
|
||||
Assert.AreEqual("localos", actual[0].Domain);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetRootLocalOsGroups() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
|
||||
// Act
|
||||
var actual = ssoAdminClient.GetGroups("", "localos").ToArray();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(actual);
|
||||
Assert.Greater(actual.Length, 1);
|
||||
Assert.AreEqual("localos", actual[0].Domain);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddRemoveUserFromGroup() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
|
||||
var expectedUserName = "test-user5";
|
||||
var expectedPassword = "te$tPa$sW0rd";
|
||||
var newUser = ssoAdminClient.CreateLocalUser(
|
||||
expectedUserName,
|
||||
expectedPassword);
|
||||
|
||||
var group = ssoAdminClient.GetGroups("administrators", newUser.Domain).FirstOrDefault<Group>();
|
||||
|
||||
// Act
|
||||
var addActual = ssoAdminClient.AddPersonUserToGroup(newUser, group);
|
||||
var removeActual = ssoAdminClient.RemovePersonUserFromGroup(newUser, group);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(addActual);
|
||||
Assert.IsTrue(removeActual);
|
||||
|
||||
// Cleanup
|
||||
ssoAdminClient.DeleteLocalUser(
|
||||
newUser);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ResetUserPassword() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
|
||||
var expectedUserName = "test-user6";
|
||||
var expectedPassword = "te$tPa$sW0rd";
|
||||
var updatePassword = "TE$tPa$sW0rd";
|
||||
var newUser = ssoAdminClient.CreateLocalUser(
|
||||
expectedUserName,
|
||||
expectedPassword);
|
||||
|
||||
// Act
|
||||
// Assert
|
||||
Assert.DoesNotThrow(() => {
|
||||
ssoAdminClient.ResetPersonUserPassword(newUser, updatePassword);
|
||||
});
|
||||
|
||||
|
||||
// Cleanup
|
||||
ssoAdminClient.DeleteLocalUser(
|
||||
newUser);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetPasswordPolicy() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
|
||||
// Act
|
||||
var actual = ssoAdminClient.GetPasswordPolicy();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetPasswordPolicy() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
|
||||
var originalPasswordPolicy = ssoAdminClient.GetPasswordPolicy();
|
||||
|
||||
var expectedDescription = "TestDescription";
|
||||
var expectedProhibitedPreviousPasswordsCount = originalPasswordPolicy.ProhibitedPreviousPasswordsCount + 1;
|
||||
var expectedMinLength = originalPasswordPolicy.MinLength + 1;
|
||||
var expectedMaxLength = originalPasswordPolicy.MaxLength + 1;
|
||||
var exptectedMaxIdenticalAdjacentCharacters = originalPasswordPolicy.MaxIdenticalAdjacentCharacters + 1;
|
||||
var expectedMinNumericCount = originalPasswordPolicy.MinNumericCount + 1;
|
||||
var expectedMinSpecialCharCount = originalPasswordPolicy.MinSpecialCharCount + 1;
|
||||
var expectedMinAlphabeticCount = originalPasswordPolicy.MinAlphabeticCount + 2;
|
||||
var expectedMinUppercaseCount = 0;
|
||||
var expectedMinLowercaseCount = originalPasswordPolicy.MinLowercaseCount + 2;
|
||||
var expectedPasswordLifetimeDays = originalPasswordPolicy.PasswordLifetimeDays - 2;
|
||||
|
||||
// Act
|
||||
var actual = ssoAdminClient.SetPasswordPolicy(
|
||||
description: expectedDescription,
|
||||
prohibitedPreviousPasswordsCount: expectedProhibitedPreviousPasswordsCount,
|
||||
minLength: expectedMinLength,
|
||||
maxLength: expectedMaxLength,
|
||||
maxIdenticalAdjacentCharacters: exptectedMaxIdenticalAdjacentCharacters,
|
||||
minNumericCount: expectedMinNumericCount,
|
||||
minSpecialCharCount: expectedMinSpecialCharCount,
|
||||
minAlphabeticCount: expectedMinAlphabeticCount,
|
||||
minUppercaseCount: expectedMinUppercaseCount,
|
||||
minLowercaseCount: expectedMinLowercaseCount,
|
||||
passwordLifetimeDays: expectedPasswordLifetimeDays);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(actual);
|
||||
Assert.AreEqual(expectedDescription, actual.Description);
|
||||
Assert.AreEqual(expectedProhibitedPreviousPasswordsCount, actual.ProhibitedPreviousPasswordsCount);
|
||||
Assert.AreEqual(expectedMinLength, actual.MinLength);
|
||||
Assert.AreEqual(expectedMaxLength, actual.MaxLength);
|
||||
Assert.AreEqual(exptectedMaxIdenticalAdjacentCharacters, actual.MaxIdenticalAdjacentCharacters);
|
||||
Assert.AreEqual(expectedMinNumericCount, actual.MinNumericCount);
|
||||
Assert.AreEqual(expectedMinAlphabeticCount, actual.MinAlphabeticCount);
|
||||
Assert.AreEqual(expectedMinUppercaseCount, actual.MinUppercaseCount);
|
||||
Assert.AreEqual(expectedMinLowercaseCount, actual.MinLowercaseCount);
|
||||
Assert.AreEqual(expectedPasswordLifetimeDays, actual.PasswordLifetimeDays);
|
||||
|
||||
// Cleanup
|
||||
ssoAdminClient.SetPasswordPolicy(
|
||||
description: originalPasswordPolicy.Description,
|
||||
prohibitedPreviousPasswordsCount: originalPasswordPolicy.ProhibitedPreviousPasswordsCount,
|
||||
minLength: originalPasswordPolicy.MinLength,
|
||||
maxLength: originalPasswordPolicy.MaxLength,
|
||||
maxIdenticalAdjacentCharacters: originalPasswordPolicy.MaxIdenticalAdjacentCharacters,
|
||||
minNumericCount: originalPasswordPolicy.MinNumericCount,
|
||||
minSpecialCharCount: originalPasswordPolicy.MinSpecialCharCount,
|
||||
minAlphabeticCount: originalPasswordPolicy.MinAlphabeticCount,
|
||||
minUppercaseCount: originalPasswordPolicy.MinUppercaseCount,
|
||||
minLowercaseCount: originalPasswordPolicy.MinLowercaseCount,
|
||||
passwordLifetimeDays: originalPasswordPolicy.PasswordLifetimeDays);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetLockoutPolicy() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
|
||||
// Act
|
||||
var actual = ssoAdminClient.GetLockoutPolicy();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetLockoutPolicy() {
|
||||
// Arrange
|
||||
var ssoAdminClient = new SsoAdminClient(_vc, _user, _password, new AcceptAllX509CertificateValidator());
|
||||
var originalLockoutPolicy = ssoAdminClient.GetLockoutPolicy();
|
||||
var expectedDescription = "TestDescription";
|
||||
var expectedAutoUnlockIntervalSec = 20;
|
||||
var expectedFailedAttemptIntervalSec = 30;
|
||||
var expectedMaxFailedAttempts = 5;
|
||||
|
||||
// Act
|
||||
var actual = ssoAdminClient.SetLockoutPolicy(
|
||||
expectedDescription,
|
||||
expectedAutoUnlockIntervalSec,
|
||||
expectedFailedAttemptIntervalSec,
|
||||
expectedMaxFailedAttempts);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(actual);
|
||||
Assert.AreEqual(expectedDescription, actual.Description);
|
||||
Assert.AreEqual(expectedAutoUnlockIntervalSec, actual.AutoUnlockIntervalSec);
|
||||
Assert.AreEqual(expectedFailedAttemptIntervalSec, actual.FailedAttemptIntervalSec);
|
||||
Assert.AreEqual(expectedMaxFailedAttempts, actual.MaxFailedAttempts);
|
||||
|
||||
// Cleanup
|
||||
ssoAdminClient.SetLockoutPolicy(
|
||||
originalLockoutPolicy.Description,
|
||||
originalLockoutPolicy.AutoUnlockIntervalSec,
|
||||
originalLockoutPolicy.FailedAttemptIntervalSec,
|
||||
originalLockoutPolicy.MaxFailedAttempts
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="nunit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VMware.vSphere.SsoAdmin.Utils\VMware.vSphere.SsoAdmin.Utils.csproj" />
|
||||
<ProjectReference Include="..\VMware.vSphere.SsoAdminClient\VMware.vSphere.SsoAdminClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,21 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient.DataTypes
|
||||
{
|
||||
public class Group
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Domain { get; set; }
|
||||
|
||||
public override string ToString() {
|
||||
return $"{Name}@{Domain}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.ServiceModel.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient.DataTypes
|
||||
{
|
||||
public class LockoutPolicy
|
||||
{
|
||||
SsoAdminClient _client;
|
||||
public LockoutPolicy(SsoAdminClient client) {
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public SsoAdminClient GetClient() {
|
||||
return _client;
|
||||
}
|
||||
|
||||
public string Description { get; set; }
|
||||
public long AutoUnlockIntervalSec { get; set; }
|
||||
public long FailedAttemptIntervalSec { get; set; }
|
||||
public int MaxFailedAttempts { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient.DataTypes
|
||||
{
|
||||
public class PasswordPolicy
|
||||
{
|
||||
SsoAdminClient _client;
|
||||
public PasswordPolicy(SsoAdminClient client) {
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public string Description { get; set; }
|
||||
public int ProhibitedPreviousPasswordsCount { get; set; }
|
||||
public int MinLength { get; set; }
|
||||
public int MaxLength { get; set; }
|
||||
public int MinNumericCount { get; set; }
|
||||
public int MinSpecialCharCount { get; set; }
|
||||
public int MaxIdenticalAdjacentCharacters { get; set; }
|
||||
public int MinAlphabeticCount { get; set; }
|
||||
public int MinUppercaseCount { get; set; }
|
||||
public int MinLowercaseCount { get; set; }
|
||||
public int PasswordLifetimeDays { get; set; }
|
||||
|
||||
public SsoAdminClient GetClient() {
|
||||
return _client;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient.DataTypes
|
||||
{
|
||||
public class PersonUser
|
||||
{
|
||||
SsoAdminClient _client;
|
||||
public PersonUser(SsoAdminClient client) {
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Domain { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string EmailAddress { get; set; }
|
||||
|
||||
public SsoAdminClient GetClient() {
|
||||
return _client;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return $"{Name}@{Domain}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Selectors;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VMware.Binding.Sts.StsService;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient.DataTypes
|
||||
{
|
||||
public class SsoAdminServer {
|
||||
|
||||
private SsoAdminClient _client;
|
||||
|
||||
public SsoAdminServer(string hostname,
|
||||
string user,
|
||||
SecureString password,
|
||||
X509CertificateValidator serverCertificateValidator) {
|
||||
|
||||
Name = hostname;
|
||||
|
||||
_client = new SsoAdminClient(
|
||||
hostname,
|
||||
user,
|
||||
password,
|
||||
serverCertificateValidator);
|
||||
|
||||
Id = $"/SsoAdminServer={NormalizeUserName()}@{Name}";
|
||||
}
|
||||
|
||||
private string NormalizeUserName() {
|
||||
string result = User;
|
||||
if (User.Contains('@')) {
|
||||
var parts = User.Split('@');
|
||||
var userName = parts[0];
|
||||
var domain = parts[1];
|
||||
result = $"{domain}/{userName}";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public Uri ServiceUri => _client?.ServiceUri;
|
||||
public string User => _client?.User;
|
||||
public string Id { get; set; }
|
||||
public bool IsConnected => _client != null;
|
||||
public SsoAdminClient Client => _client;
|
||||
|
||||
public void Disconnect() {
|
||||
_client = null;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return Id != null ? Id.GetHashCode() : base.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
bool result = false;
|
||||
if (obj is SsoAdminServer target) {
|
||||
result = string.Equals(Id, target.Id);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient.DataTypes
|
||||
{
|
||||
public class TokenLifetime
|
||||
{
|
||||
SsoAdminClient _client;
|
||||
public TokenLifetime(SsoAdminClient client) {
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public SsoAdminClient GetClient() {
|
||||
return _client;
|
||||
}
|
||||
|
||||
public long MaxHoKTokenLifetime { get; set; }
|
||||
public long MaxBearerTokenLifetime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,661 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Selectors;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Security;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Security;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using VMware.Binding.WsTrust;
|
||||
using VMware.Binding.WsTrust.SecurityContext;
|
||||
using VMware.vSphere.LsClient;
|
||||
using VMware.vSphere.SsoAdminClient.DataTypes;
|
||||
using VMware.vSphere.SsoAdminClient.SsoAdminServiceReferencer;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient
|
||||
{
|
||||
public class SsoAdminClient
|
||||
{
|
||||
private const int WEB_OPERATION_TIMEOUT_SECONDS = 30;
|
||||
|
||||
private SsoPortTypeClient _ssoAdminBindingClient;
|
||||
private UserPassSecurityContext _securityContext;
|
||||
|
||||
public SsoAdminClient(string hostname, string user, SecureString password, X509CertificateValidator serverCertificateValidator) {
|
||||
if (hostname == null) throw new ArgumentNullException(nameof(hostname));
|
||||
if (user == null) throw new ArgumentNullException(nameof(user));
|
||||
if (password == null) throw new ArgumentNullException(nameof(password));
|
||||
|
||||
var lsClient = new LookupServiceClient(hostname, serverCertificateValidator);
|
||||
|
||||
// Create STS Client
|
||||
var stsUri = lsClient.GetStsEndpointUri();
|
||||
_securityContext = new UserPassSecurityContext(user, password, stsUri, serverCertificateValidator);
|
||||
// Initialize security context with Saml token by username and password
|
||||
_securityContext.GetToken();
|
||||
|
||||
// Create SSO Admin Binding Client
|
||||
var ssoAdminUri = lsClient.GetSsoAdminEndpointUri();
|
||||
ServiceUri = ssoAdminUri;
|
||||
User = user;
|
||||
_ssoAdminBindingClient = new SsoPortTypeClient(GetBinding(), new EndpointAddress(ssoAdminUri));
|
||||
_ssoAdminBindingClient.ChannelFactory.Endpoint.EndpointBehaviors.Add(new WsTrustBehavior());
|
||||
|
||||
var serverAuthentication = GetServerAuthentication(serverCertificateValidator);
|
||||
|
||||
if (serverAuthentication != null) {
|
||||
_ssoAdminBindingClient
|
||||
.ChannelFactory
|
||||
.Credentials
|
||||
.ServiceCertificate
|
||||
.SslCertificateAuthentication = serverAuthentication;
|
||||
}
|
||||
}
|
||||
|
||||
#region Private Helpers
|
||||
private X509ServiceCertificateAuthentication GetServerAuthentication(X509CertificateValidator serverCertificateValidator) {
|
||||
if (serverCertificateValidator != null) {
|
||||
return new X509ServiceCertificateAuthentication {
|
||||
CertificateValidationMode = X509CertificateValidationMode.Custom,
|
||||
CustomCertificateValidator = serverCertificateValidator
|
||||
};
|
||||
}
|
||||
|
||||
// Default .NET behavior for TLS certificate validation
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MessageEncodingBindingElement GetWcfEncoding() {
|
||||
// VMware STS requires SOAP version 1.1
|
||||
return new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
|
||||
}
|
||||
|
||||
private static HttpsTransportBindingElement GetWcfTransport(bool useSystemProxy) {
|
||||
// Communication with the STS is over https
|
||||
HttpsTransportBindingElement transport = new HttpsTransportBindingElement {
|
||||
RequireClientCertificate = false
|
||||
};
|
||||
|
||||
transport.UseDefaultWebProxy = useSystemProxy;
|
||||
transport.MaxBufferSize = 2147483647;
|
||||
transport.MaxReceivedMessageSize = 2147483647;
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
||||
private static CustomBinding GetBinding() {
|
||||
|
||||
// There is no build-in WCF binding capable of communicating
|
||||
// with VMware STS, so we create a plain custom one.
|
||||
// This binding does not provide support for WS-Trust,
|
||||
// that support is currently implemented as a WCF endpoint behaviour.
|
||||
var binding = new CustomBinding(GetWcfEncoding(), GetWcfTransport(true));
|
||||
|
||||
var timeout = TimeSpan.FromSeconds(WEB_OPERATION_TIMEOUT_SECONDS);
|
||||
binding.CloseTimeout = timeout;
|
||||
binding.OpenTimeout = timeout;
|
||||
binding.ReceiveTimeout = timeout;
|
||||
binding.SendTimeout = timeout;
|
||||
|
||||
return binding;
|
||||
}
|
||||
|
||||
private WsSecurityContext CreateAuthorizedInvocationContext() {
|
||||
// Issue Bearer token to authorize create solution user to SSO Admin service
|
||||
var bearerToken = _securityContext.GetToken();
|
||||
|
||||
// Set WS Trust Header Serialization with issued bearer SAML token
|
||||
var securityContext = new WsSecurityContext {
|
||||
ClientChannel = _ssoAdminBindingClient.InnerChannel,
|
||||
Properties = {
|
||||
Credentials = {
|
||||
BearerToken = bearerToken
|
||||
}
|
||||
}
|
||||
};
|
||||
return securityContext;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public interface
|
||||
|
||||
public Uri ServiceUri { get; }
|
||||
public string User { get; }
|
||||
|
||||
public PersonUser CreateLocalUser(
|
||||
string userName,
|
||||
string password,
|
||||
string description = null,
|
||||
string emailAddress = null,
|
||||
string firstName = null,
|
||||
string lastName = null) {
|
||||
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin CreateLocalSolutionUser operation
|
||||
var ssoPrincipalId = authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.CreateLocalPersonUserAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalManagementService",
|
||||
Value = "principalManagementService"
|
||||
},
|
||||
userName,
|
||||
new SsoAdminPersonDetails {
|
||||
description = description,
|
||||
emailAddress = emailAddress,
|
||||
firstName = firstName,
|
||||
lastName = lastName
|
||||
},
|
||||
password)).Result;
|
||||
|
||||
return GetLocalUsers(ssoPrincipalId.name, ssoPrincipalId.domain, authorizedInvocationContext);
|
||||
}
|
||||
|
||||
private PersonUser GetLocalUsers(string userName, string domain, WsSecurityContext wsSecurityContext) {
|
||||
// Invoke SSO Admin FindPersonUserAsync operation
|
||||
var personUser = wsSecurityContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.FindPersonUserAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalDiscoveryService",
|
||||
Value = "principalDiscoveryService"
|
||||
},
|
||||
new SsoPrincipalId {
|
||||
name = userName,
|
||||
domain = domain
|
||||
})).Result;
|
||||
return new PersonUser(this) {
|
||||
Name = personUser.id.name,
|
||||
Domain = personUser.id.domain,
|
||||
Description = personUser.details.description,
|
||||
FirstName = personUser.details.firstName,
|
||||
LastName = personUser.details.lastName,
|
||||
EmailAddress = personUser.details.emailAddress
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<PersonUser> GetLocalUsers(string searchString, string domain) {
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin FindPersonUsersAsync operation
|
||||
var personUsers = authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.FindPersonUsersAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalDiscoveryService",
|
||||
Value = "principalDiscoveryService"
|
||||
},
|
||||
new SsoAdminPrincipalDiscoveryServiceSearchCriteria {
|
||||
searchString = searchString,
|
||||
domain = domain
|
||||
},
|
||||
int.MaxValue)).Result.returnval;
|
||||
|
||||
if (personUsers != null) {
|
||||
foreach (var personUser in personUsers) {
|
||||
yield return new PersonUser(this) {
|
||||
Name = personUser.id.name,
|
||||
Domain = personUser.id.domain,
|
||||
Description = personUser.details.description,
|
||||
FirstName = personUser.details.firstName,
|
||||
LastName = personUser.details.lastName,
|
||||
EmailAddress = personUser.details.emailAddress
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void DeleteLocalUser(
|
||||
PersonUser principal) {
|
||||
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin DeleteLocalPrincipal operation
|
||||
authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.DeleteLocalPrincipalAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalManagementService",
|
||||
Value = "principalManagementService"
|
||||
},
|
||||
principal.Name));
|
||||
}
|
||||
|
||||
public IEnumerable<DataTypes.Group> GetGroups(string searchString, string domain) {
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin FindGroupsAsync operation
|
||||
var ssoAdminGroups = authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.FindGroupsAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalDiscoveryService",
|
||||
Value = "principalDiscoveryService"
|
||||
},
|
||||
new SsoAdminPrincipalDiscoveryServiceSearchCriteria {
|
||||
searchString = searchString,
|
||||
domain = domain
|
||||
},
|
||||
int.MaxValue)).Result.returnval;
|
||||
|
||||
if (ssoAdminGroups != null) {
|
||||
foreach (var group in ssoAdminGroups) {
|
||||
yield return new DataTypes.Group {
|
||||
Name = group.id.name,
|
||||
Domain = group.id.domain
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddPersonUserToGroup(PersonUser user, DataTypes.Group group) {
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin AddUserToLocalGroupAsync operation
|
||||
return authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.AddUserToLocalGroupAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalManagementService",
|
||||
Value = "principalManagementService"
|
||||
},
|
||||
new SsoPrincipalId {
|
||||
name = user.Name,
|
||||
domain = user.Domain
|
||||
},
|
||||
group.Name)).Result;
|
||||
}
|
||||
|
||||
public bool RemovePersonUserFromGroup(PersonUser user, DataTypes.Group group) {
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin RemoveFromLocalGroupAsync operation
|
||||
return authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.RemoveFromLocalGroupAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalManagementService",
|
||||
Value = "principalManagementService"
|
||||
},
|
||||
new SsoPrincipalId {
|
||||
name = user.Name,
|
||||
domain = user.Domain
|
||||
},
|
||||
group.Name)).Result;
|
||||
}
|
||||
|
||||
public void ResetPersonUserPassword(PersonUser user, string newPassword) {
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin ResetLocalPersonUserPasswordAsync operation
|
||||
authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.ResetLocalPersonUserPasswordAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalManagementService",
|
||||
Value = "principalManagementService"
|
||||
},
|
||||
user.Name,
|
||||
newPassword)).Wait();
|
||||
}
|
||||
|
||||
public bool UnlockPersonUser(PersonUser user) {
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin UnlockUserAccountAsync operation
|
||||
return authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.UnlockUserAccountAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPrincipalManagementService",
|
||||
Value = "principalManagementService"
|
||||
},
|
||||
new SsoPrincipalId {
|
||||
name = user.Name,
|
||||
domain = user.Domain
|
||||
})).Result;
|
||||
}
|
||||
|
||||
public PasswordPolicy GetPasswordPolicy() {
|
||||
PasswordPolicy result = null;
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin GetLocalPasswordPolicyAsync operation
|
||||
var ssoAdminPasswordPolicy = authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.GetLocalPasswordPolicyAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPasswordPolicyService",
|
||||
Value = "passwordPolicyService"
|
||||
})).Result;
|
||||
|
||||
if (ssoAdminPasswordPolicy != null) {
|
||||
result = new PasswordPolicy(this) {
|
||||
Description = ssoAdminPasswordPolicy.description,
|
||||
ProhibitedPreviousPasswordsCount = ssoAdminPasswordPolicy.prohibitedPreviousPasswordsCount,
|
||||
MinLength = ssoAdminPasswordPolicy.passwordFormat.lengthRestriction.minLength,
|
||||
MaxLength = ssoAdminPasswordPolicy.passwordFormat.lengthRestriction.maxLength,
|
||||
MaxIdenticalAdjacentCharacters = ssoAdminPasswordPolicy.passwordFormat.maxIdenticalAdjacentCharacters,
|
||||
MinNumericCount = ssoAdminPasswordPolicy.passwordFormat.minNumericCount,
|
||||
MinSpecialCharCount = ssoAdminPasswordPolicy.passwordFormat.minSpecialCharCount,
|
||||
MinAlphabeticCount = ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minAlphabeticCount,
|
||||
MinUppercaseCount = ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minUppercaseCount,
|
||||
MinLowercaseCount = ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minLowercaseCount,
|
||||
PasswordLifetimeDays = ssoAdminPasswordPolicy.passwordLifetimeDays
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public PasswordPolicy SetPasswordPolicy(
|
||||
string description = null,
|
||||
int? prohibitedPreviousPasswordsCount = null,
|
||||
int? minLength = null,
|
||||
int? maxLength = null,
|
||||
int? maxIdenticalAdjacentCharacters = null,
|
||||
int? minNumericCount = null,
|
||||
int? minSpecialCharCount = null,
|
||||
int? minAlphabeticCount = null,
|
||||
int? minUppercaseCount = null,
|
||||
int? minLowercaseCount = null,
|
||||
int? passwordLifetimeDays = null) {
|
||||
|
||||
if (description != null ||
|
||||
prohibitedPreviousPasswordsCount != null ||
|
||||
minLength != null ||
|
||||
maxLength != null ||
|
||||
maxIdenticalAdjacentCharacters != null ||
|
||||
minNumericCount != null ||
|
||||
minSpecialCharCount != null ||
|
||||
minAlphabeticCount != null ||
|
||||
minUppercaseCount != null ||
|
||||
minLowercaseCount != null ||
|
||||
passwordLifetimeDays != null) {
|
||||
|
||||
var ssoAdminPasswordPolicy = new SsoAdminPasswordPolicy();
|
||||
ssoAdminPasswordPolicy.description = description;
|
||||
|
||||
if (passwordLifetimeDays != null) {
|
||||
ssoAdminPasswordPolicy.passwordLifetimeDays = passwordLifetimeDays.Value;
|
||||
ssoAdminPasswordPolicy.passwordLifetimeDaysSpecified = true;
|
||||
}
|
||||
|
||||
if (prohibitedPreviousPasswordsCount != null) {
|
||||
ssoAdminPasswordPolicy.prohibitedPreviousPasswordsCount = prohibitedPreviousPasswordsCount.Value;
|
||||
}
|
||||
|
||||
// Update SsoAdminPasswordFormat if needed
|
||||
if (minLength != null ||
|
||||
maxLength != null ||
|
||||
maxIdenticalAdjacentCharacters != null ||
|
||||
minNumericCount != null ||
|
||||
minSpecialCharCount != null ||
|
||||
minAlphabeticCount != null ||
|
||||
minUppercaseCount != null ||
|
||||
minLowercaseCount != null) {
|
||||
|
||||
ssoAdminPasswordPolicy.passwordFormat = new SsoAdminPasswordFormat();
|
||||
|
||||
if (maxIdenticalAdjacentCharacters != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.maxIdenticalAdjacentCharacters = maxIdenticalAdjacentCharacters.Value;
|
||||
}
|
||||
|
||||
if (minNumericCount != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.minNumericCount = minNumericCount.Value;
|
||||
}
|
||||
|
||||
if (minSpecialCharCount != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.minSpecialCharCount = minSpecialCharCount.Value;
|
||||
}
|
||||
|
||||
// Update LengthRestriction if needed
|
||||
if (minLength != null ||
|
||||
maxLength != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.lengthRestriction = new SsoAdminPasswordFormatLengthRestriction();
|
||||
if (maxLength != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.lengthRestriction.maxLength = maxLength.Value;
|
||||
}
|
||||
if (minLength != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.lengthRestriction.minLength = minLength.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// Update AlphabeticRestriction if needed
|
||||
if (minAlphabeticCount != null ||
|
||||
minUppercaseCount != null ||
|
||||
minLowercaseCount != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction = new SsoAdminPasswordFormatAlphabeticRestriction();
|
||||
|
||||
if (minAlphabeticCount != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minAlphabeticCount = minAlphabeticCount.Value;
|
||||
}
|
||||
|
||||
if (minUppercaseCount != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minUppercaseCount = minUppercaseCount.Value;
|
||||
}
|
||||
|
||||
if (minLowercaseCount != null) {
|
||||
ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minLowercaseCount = minLowercaseCount.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin UpdateLocalPasswordPolicyAsync operation
|
||||
authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.UpdateLocalPasswordPolicyAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminPasswordPolicyService",
|
||||
Value = "passwordPolicyService"
|
||||
},
|
||||
ssoAdminPasswordPolicy)).Wait();
|
||||
}
|
||||
|
||||
return GetPasswordPolicy();
|
||||
}
|
||||
|
||||
public LockoutPolicy GetLockoutPolicy() {
|
||||
LockoutPolicy result = null;
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin GetLockoutPolicyAsync operation
|
||||
var ssoAdminLockoutPolicy = authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.GetLockoutPolicyAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminLockoutPolicyService",
|
||||
Value = "lockoutPolicyService"
|
||||
})).Result;
|
||||
|
||||
if (ssoAdminLockoutPolicy != null) {
|
||||
result = new LockoutPolicy(this) {
|
||||
Description = ssoAdminLockoutPolicy.description,
|
||||
AutoUnlockIntervalSec = ssoAdminLockoutPolicy.autoUnlockIntervalSec,
|
||||
FailedAttemptIntervalSec = ssoAdminLockoutPolicy.failedAttemptIntervalSec,
|
||||
MaxFailedAttempts = ssoAdminLockoutPolicy.maxFailedAttempts
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public LockoutPolicy SetLockoutPolicy(
|
||||
string description,
|
||||
long? autoUnlockIntervalSec,
|
||||
long? failedAttemptIntervalSec,
|
||||
int? maxFailedAttempts) {
|
||||
|
||||
if (description != null ||
|
||||
autoUnlockIntervalSec != null ||
|
||||
failedAttemptIntervalSec != null ||
|
||||
maxFailedAttempts != null) {
|
||||
|
||||
var ssoAdminLockoutPolicy = new SsoAdminLockoutPolicy();
|
||||
|
||||
ssoAdminLockoutPolicy.description = description;
|
||||
|
||||
if (autoUnlockIntervalSec != null) {
|
||||
ssoAdminLockoutPolicy.autoUnlockIntervalSec = autoUnlockIntervalSec.Value;
|
||||
}
|
||||
|
||||
if (failedAttemptIntervalSec != null) {
|
||||
ssoAdminLockoutPolicy.failedAttemptIntervalSec = failedAttemptIntervalSec.Value;
|
||||
}
|
||||
|
||||
if (maxFailedAttempts != null) {
|
||||
ssoAdminLockoutPolicy.maxFailedAttempts = maxFailedAttempts.Value;
|
||||
}
|
||||
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
// Invoke SSO Admin GetLockoutPolicyAsync operation
|
||||
authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.UpdateLockoutPolicyAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminLockoutPolicyService",
|
||||
Value = "lockoutPolicyService"
|
||||
},
|
||||
ssoAdminLockoutPolicy)).Wait();
|
||||
|
||||
}
|
||||
|
||||
return GetLockoutPolicy();
|
||||
}
|
||||
|
||||
public TokenLifetime GetTokenLifetime() {
|
||||
|
||||
// Create Authorization Invocation Context
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
var maxHoKTokenLifetime = authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.GetMaximumHoKTokenLifetimeAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminConfigurationManagementService",
|
||||
Value = "configurationManagementService"
|
||||
})).Result;
|
||||
|
||||
var maxBearerTokenLifetime = authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.GetMaximumBearerTokenLifetimeAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminConfigurationManagementService",
|
||||
Value = "configurationManagementService"
|
||||
})).Result;
|
||||
|
||||
return new TokenLifetime(this) {
|
||||
MaxHoKTokenLifetime = maxHoKTokenLifetime,
|
||||
MaxBearerTokenLifetime = maxBearerTokenLifetime
|
||||
};
|
||||
}
|
||||
|
||||
public TokenLifetime SetTokenLifetime(
|
||||
long? maxHoKTokenLifetime,
|
||||
long? maxBearerTokenLifetime) {
|
||||
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
if (maxHoKTokenLifetime != null) {
|
||||
authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.SetMaximumHoKTokenLifetimeAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminConfigurationManagementService",
|
||||
Value = "configurationManagementService"
|
||||
},
|
||||
maxHoKTokenLifetime.Value)).Wait();
|
||||
}
|
||||
|
||||
if (maxBearerTokenLifetime != null) {
|
||||
authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.SetMaximumBearerTokenLifetimeAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminConfigurationManagementService",
|
||||
Value = "configurationManagementService"
|
||||
},
|
||||
maxBearerTokenLifetime.Value)).Wait();
|
||||
}
|
||||
|
||||
|
||||
return GetTokenLifetime();
|
||||
}
|
||||
|
||||
public void AddActiveDirectoryExternalDomain(
|
||||
string domainName,
|
||||
string domainAlias,
|
||||
string friendlyName,
|
||||
string primaryUrl,
|
||||
string baseDNUsers,
|
||||
string baseDNGroups,
|
||||
string authenticationUserName,
|
||||
string authenticationPassword) {
|
||||
|
||||
string serverType = "ActiveDirectory";
|
||||
string authenticationType = "password";
|
||||
var authorizedInvocationContext =
|
||||
CreateAuthorizedInvocationContext();
|
||||
|
||||
authorizedInvocationContext.
|
||||
InvokeOperation(() =>
|
||||
_ssoAdminBindingClient.AddExternalDomainAsync(
|
||||
new ManagedObjectReference {
|
||||
type = "SsoAdminConfigurationManagementService",
|
||||
Value = "configurationManagementService"
|
||||
},
|
||||
serverType,
|
||||
domainName,
|
||||
domainAlias,
|
||||
new SsoAdminExternalDomainDetails {
|
||||
friendlyName = friendlyName,
|
||||
primaryUrl = primaryUrl,
|
||||
userBaseDn = baseDNUsers,
|
||||
groupBaseDn = baseDNGroups
|
||||
},
|
||||
authenticationType,
|
||||
new SsoAdminDomainManagementServiceAuthenticationCredentails {
|
||||
username = authenticationUserName,
|
||||
password = authenticationPassword
|
||||
})).Wait();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
// **************************************************************************
|
||||
// Copyright 2020 VMware, Inc.
|
||||
// **************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Selectors;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using VMware.Binding.Sts;
|
||||
|
||||
namespace VMware.vSphere.SsoAdminClient
|
||||
{
|
||||
public class UserPassSecurityContext
|
||||
{
|
||||
private string _user;
|
||||
private SecureString _password;
|
||||
private VmwareSecruityTokenService _stsClient;
|
||||
private SamlSecurityToken _validToken;
|
||||
public UserPassSecurityContext(
|
||||
string user,
|
||||
SecureString password,
|
||||
Uri stsUri,
|
||||
X509CertificateValidator serverCertificateValidator) {
|
||||
|
||||
if (user == null) throw new ArgumentNullException(nameof(user));
|
||||
if (password == null) throw new ArgumentNullException(nameof(password));
|
||||
if (stsUri == null) throw new ArgumentNullException(nameof(stsUri));
|
||||
|
||||
_user = user;
|
||||
_password = password;
|
||||
|
||||
Action<X509Certificate2> certHandler = null;
|
||||
if (serverCertificateValidator != null) {
|
||||
certHandler = serverCertificateValidator.Validate;
|
||||
}
|
||||
_stsClient = new VmwareSecruityTokenService(stsUri, false, certHandler);
|
||||
}
|
||||
|
||||
private void RenewIfNeeded() {
|
||||
if (_validToken == null ||
|
||||
_validToken.Expires < (DateTime.Now + new TimeSpan(0, 0, 30))) {
|
||||
_validToken = _stsClient.IssueBearerTokenByUserCredential(
|
||||
_user,
|
||||
_password);
|
||||
}
|
||||
}
|
||||
|
||||
public XmlElement GetToken() {
|
||||
RenewIfNeeded();
|
||||
return _validToken.RawToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>VMware.vSphere.SsoAdminClient</RootNamespace>
|
||||
<AssemblyName>VMware.vSphere.SsoAdminClient</AssemblyName>
|
||||
<Description>SSO Admin API client.</Description>
|
||||
<TargetFrameworks>net45;netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'net45' ">
|
||||
<DefineConstants>$(DefineConstants);NET45</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">
|
||||
<DefineConstants>$(DefineConstants);NETCORE20</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
|
||||
<Reference Include="System.IdentityModel" />
|
||||
<PackageReference Include="System.ServiceModel.Primitives" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Duplex" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Http" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.4.0" />
|
||||
<PackageReference Include="System.ServiceModel.Security" Version="4.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
|
||||
<PackageReference Include="VMware.System.Private.ServiceModel" Version="4.4.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="VMware.Binding.Sts" Version="12.0.0.15939652" />
|
||||
<PackageReference Include="VMware.Binding.WsTrust" Version="12.0.0.15939652" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VMware.vSphere.LsClient\VMware.vSphere.LsClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
147
Modules/VMware.vSphere.SsoAdmin/src/build.ps1
Normal file
147
Modules/VMware.vSphere.SsoAdmin/src/build.ps1
Normal file
@@ -0,0 +1,147 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[ValidateSet("Debug", "Release")]
|
||||
[string]
|
||||
$Configuration = "Release",
|
||||
|
||||
[string]
|
||||
$TestVc,
|
||||
|
||||
[string]
|
||||
$TestVcUser,
|
||||
|
||||
[string]
|
||||
$TestVcPassword
|
||||
)
|
||||
|
||||
function Test-BuildToolsAreAvailable {
|
||||
$dotnetSdk = Get-Command 'dotnet'
|
||||
if (-not $dotnetSdk) {
|
||||
throw "'dotnet' sdk is not available"
|
||||
}
|
||||
}
|
||||
|
||||
function LogInfo($message) {
|
||||
$dt = (Get-Date).ToLongTimeString()
|
||||
Write-Host "[$dt] INFO: $message" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Build {
|
||||
$srcRoot = Join-Path $PSScriptRoot "VMware.vSphere.SsoAdmin.Client"
|
||||
|
||||
Push-Location $srcRoot
|
||||
|
||||
dotnet build -c $Configuration
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
function Publish {
|
||||
param($OutputFolder)
|
||||
|
||||
if (Test-Path $OutputFolder) {
|
||||
$netcoreLsSource = [IO.Path]::Combine(
|
||||
$PSScriptRoot,
|
||||
"VMware.vSphere.SsoAdmin.Client",
|
||||
"VMware.vSphere.LsClient",
|
||||
"bin",
|
||||
$Configuration,
|
||||
"netcoreapp2.0",
|
||||
"VMware.vSphere.LsClient.dll")
|
||||
|
||||
$net45LsSource = [IO.Path]::Combine(
|
||||
$PSScriptRoot,
|
||||
"VMware.vSphere.SsoAdmin.Client",
|
||||
"VMware.vSphere.LsClient",
|
||||
"bin",
|
||||
$Configuration,
|
||||
"net45",
|
||||
"VMware.vSphere.LsClient.dll")
|
||||
|
||||
$netcoreSsoAdminSource = [IO.Path]::Combine(
|
||||
$PSScriptRoot,
|
||||
"VMware.vSphere.SsoAdmin.Client",
|
||||
"VMware.vSphere.SsoAdminClient",
|
||||
"bin",
|
||||
$Configuration,
|
||||
"netcoreapp2.0",
|
||||
"VMware.vSphere.SsoAdminClient.dll")
|
||||
|
||||
$net45SsoAdminSource = [IO.Path]::Combine(
|
||||
$PSScriptRoot,
|
||||
"VMware.vSphere.SsoAdmin.Client",
|
||||
"VMware.vSphere.SsoAdminClient",
|
||||
"bin",
|
||||
$Configuration,
|
||||
"net45",
|
||||
"VMware.vSphere.SsoAdminClient.dll")
|
||||
|
||||
$netcoreUtilsSource = [IO.Path]::Combine(
|
||||
$PSScriptRoot,
|
||||
"VMware.vSphere.SsoAdmin.Client",
|
||||
"VMware.vSphere.SsoAdmin.Utils",
|
||||
"bin",
|
||||
$Configuration,
|
||||
"netcoreapp2.0",
|
||||
"VMware.vSphere.SsoAdmin.Utils.dll")
|
||||
|
||||
$net45UtilsSource = [IO.Path]::Combine(
|
||||
$PSScriptRoot,
|
||||
"VMware.vSphere.SsoAdmin.Client",
|
||||
"VMware.vSphere.SsoAdmin.Utils",
|
||||
"bin",
|
||||
$Configuration,
|
||||
"net45",
|
||||
"VMware.vSphere.SsoAdmin.Utils.dll")
|
||||
|
||||
|
||||
$netcoreTarget = Join-Path $OutputFolder "netcoreapp2.0"
|
||||
$net45Target = Join-Path $OutputFolder "net45"
|
||||
|
||||
Copy-Item -Path $netcoreLsSource -Destination $netcoreTarget -Force
|
||||
Copy-Item -Path $net45LsSource -Destination $net45Target -Force
|
||||
Copy-Item -Path $netcoreSsoAdminSource -Destination $netcoreTarget -Force
|
||||
Copy-Item -Path $net45SsoAdminSource -Destination $net45Target -Force
|
||||
Copy-Item -Path $netcoreUtilsSource -Destination $netcoreTarget -Force
|
||||
Copy-Item -Path $net45UtilsSource -Destination $net45Target -Force
|
||||
}
|
||||
}
|
||||
|
||||
function Test {
|
||||
if (-not [string]::IsNullOrEmpty($TestVc) -and `
|
||||
-not [string]::IsNullOrEmpty($TestVcUser) -and `
|
||||
-not [string]::IsNullOrEmpty($TestVcPassword)) {
|
||||
|
||||
# Run Tests in external process because it will load build output binaries
|
||||
LogInfo "Run VC integration tests"
|
||||
$usePowerShell = (Get-Process -Id $pid).ProcessName
|
||||
$testLauncherScript = Join-Path (Join-Path $PSScriptRoot 'test') 'RunTests.ps1'
|
||||
$arguments = "-Command $testLauncherScript -VcAddress $TestVc -User $TestVcUser -Password $TestVcPassword"
|
||||
|
||||
Start-Process `
|
||||
-FilePath $usePowerShell `
|
||||
-ArgumentList $arguments `
|
||||
-PassThru `
|
||||
-NoNewWindow | `
|
||||
Wait-Process
|
||||
}
|
||||
}
|
||||
|
||||
# 1. Test Build Tools
|
||||
LogInfo "Test build tools are available"
|
||||
Test-BuildToolsAreAvailable
|
||||
|
||||
# 2. Build
|
||||
LogInfo "Build"
|
||||
Build
|
||||
|
||||
# 3. Publish
|
||||
$OutputFolder = Split-Path $PSScriptRoot
|
||||
LogInfo "Publish binaries to '$OutputFolder'"
|
||||
Publish $OutputFolder
|
||||
|
||||
# 4. Test
|
||||
Test
|
||||
@@ -0,0 +1,106 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$VcAddress,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$User,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Password
|
||||
)
|
||||
|
||||
# Import Vmware.vSphere.SsoAdmin Module
|
||||
$modulePath = Join-Path (Split-Path $PSScriptRoot | Split-Path) "VMware.vSphere.SsoAdmin.psd1"
|
||||
Import-Module $modulePath
|
||||
|
||||
Describe "Connect-SsoAdminServer and Disconnect-SsoAdminServer Tests" {
|
||||
AfterEach {
|
||||
$connectionsToCleanup = $global:DefaultSsoAdminServers.ToArray()
|
||||
foreach ($connection in $connectionsToCleanup) {
|
||||
Disconnect-SsoAdminServer -Server $connection
|
||||
}
|
||||
}
|
||||
|
||||
Context "Connect-SsoAdminServer" {
|
||||
It 'Connect-SsoAdminServer returns SsoAdminServer object and updates DefaultSsoAdminServers variable' {
|
||||
# Act
|
||||
$actual = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.GetType().FullName | Should Be 'VMware.vSphere.SsoAdminClient.DataTypes.SsoAdminServer'
|
||||
$actual.IsConnected | Should Be $true
|
||||
$actual.Name | Should Be $VcAddress
|
||||
$global:DefaultSsoAdminServers | Should Contain $actual
|
||||
}
|
||||
|
||||
It 'Connect-SsoAdminServer throws error on invalid password' {
|
||||
# Act
|
||||
# Assert
|
||||
{ Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password ($Password + "invalid") `
|
||||
-SkipCertificateCheck } | `
|
||||
Should Throw "Invalid credentials"
|
||||
}
|
||||
|
||||
It 'Connect-SsoAdminServer throws error on invalid Tls Certificate' {
|
||||
# Act
|
||||
# Assert
|
||||
{ Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password} | `
|
||||
Should Throw "The SSL connection could not be established, see inner exception."
|
||||
}
|
||||
}
|
||||
|
||||
Context "Disconnect-SsoAdminServer" {
|
||||
It 'Diconnect-SsoAdminServer removes server from DefaultSsoAdminServers and makes the object not connected' {
|
||||
# Arrange
|
||||
$expected = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
# Act
|
||||
$expected | Disconnect-SsoAdminServer
|
||||
|
||||
# Assert
|
||||
$global:DefaultSsoAdminServers | Should Not Contain $expected
|
||||
$expected.IsConnected | Should Be $false
|
||||
}
|
||||
|
||||
It 'Disconnects disconnected object' {
|
||||
# Arrange
|
||||
$expected = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$expected | Disconnect-SsoAdminServer
|
||||
|
||||
# Act
|
||||
{ Disconnect-SsoAdminServer -Server $expected } | `
|
||||
Should Not Throw
|
||||
|
||||
# Assert
|
||||
$global:DefaultSsoAdminServers | Should Not Contain $expected
|
||||
$expected.IsConnected | Should Be $false
|
||||
}
|
||||
}
|
||||
}
|
||||
76
Modules/VMware.vSphere.SsoAdmin/src/test/Group.Tests.ps1
Normal file
76
Modules/VMware.vSphere.SsoAdmin/src/test/Group.Tests.ps1
Normal file
@@ -0,0 +1,76 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$VcAddress,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$User,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Password
|
||||
)
|
||||
|
||||
# Import Vmware.vSphere.SsoAdmin Module
|
||||
$modulePath = Join-Path (Split-Path $PSScriptRoot | Split-Path) "VMware.vSphere.SsoAdmin.psd1"
|
||||
Import-Module $modulePath
|
||||
|
||||
Describe "Get-SsoGroup Tests" {
|
||||
BeforeEach {
|
||||
Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
$connectionsToCleanup = $global:DefaultSsoAdminServers.ToArray()
|
||||
foreach ($connection in $connectionsToCleanup) {
|
||||
Disconnect-SsoAdminServer -Server $connection
|
||||
}
|
||||
}
|
||||
|
||||
Context "Get-SsoGroup" {
|
||||
It 'Gets groups without filters' {
|
||||
# Act
|
||||
$actual = Get-SsoGroup
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.Count | Should BeGreaterThan 0
|
||||
$actual[0].Name | Should Not Be $null
|
||||
$actual[0].Domain | Should Be 'localos'
|
||||
}
|
||||
|
||||
It 'Gets groups for default domain' {
|
||||
# Arrange
|
||||
$newUserName = "NewUser1"
|
||||
$password = '$tr0NG_TestPa$$w0rd'
|
||||
|
||||
## Create Person User to determine default domain name
|
||||
## Person Users are created in the default domain
|
||||
$newPersonUser = New-SsoPersonUser `
|
||||
-UserName $newUserName `
|
||||
-Password $password
|
||||
|
||||
# Act
|
||||
$actual = Get-SsoGroup `
|
||||
-Domain $newPersonUser.Domain
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.Count | Should BeGreaterThan 0
|
||||
$actual[0].Name | Should Not Be $null
|
||||
$actual[0].Domain | Should Be $newPersonUser.Domain
|
||||
|
||||
# Cleanup
|
||||
Remove-SsoPersonUser -User $newPersonUser
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$VcAddress,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$User,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Password
|
||||
)
|
||||
|
||||
# Import Vmware.vSphere.SsoAdmin Module
|
||||
$modulePath = Join-Path (Split-Path $PSScriptRoot | Split-Path) "VMware.vSphere.SsoAdmin.psd1"
|
||||
Import-Module $modulePath
|
||||
|
||||
Describe "LockoutPolicy Tests" {
|
||||
BeforeEach {
|
||||
Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
$connectionsToCleanup = $global:DefaultSsoAdminServers.ToArray()
|
||||
foreach ($connection in $connectionsToCleanup) {
|
||||
Disconnect-SsoAdminServer -Server $connection
|
||||
}
|
||||
}
|
||||
|
||||
Context "Get-SsoLockoutPolicy" {
|
||||
It 'Gets lockout policy' {
|
||||
# Act
|
||||
$actual = Get-SsoLockoutPolicy
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
}
|
||||
}
|
||||
|
||||
Context "Set-SsoLockoutPolicy" {
|
||||
It 'Updates lockout policy AutoUnlockIntervalSec and MaxFailedAttempts' {
|
||||
# Arrange
|
||||
$lockoutPolicyToUpdate = Get-SsoLockoutPolicy
|
||||
$expectedAutoUnlockIntervalSec = 33
|
||||
$expectedMaxFailedAttempts = 7
|
||||
|
||||
# Act
|
||||
$actual = Set-SsoLockoutPolicy `
|
||||
-LockoutPolicy $lockoutPolicyToUpdate `
|
||||
-AutoUnlockIntervalSec $expectedAutoUnlockIntervalSec `
|
||||
-MaxFailedAttempts $expectedMaxFailedAttempts
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.AutoUnlockIntervalSec | Should Be $expectedAutoUnlockIntervalSec
|
||||
$actual.MaxFailedAttempts | Should Be $expectedMaxFailedAttempts
|
||||
$actual.FailedAttemptIntervalSec | Should Be $lockoutPolicyToUpdate.FailedAttemptIntervalSec
|
||||
$actual.Description | Should Be $lockoutPolicyToUpdate.Description
|
||||
|
||||
# Cleanup
|
||||
$lockoutPolicyToUpdate | Set-SsoLockoutPolicy
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Modules/VMware.vSphere.SsoAdmin/src/test/LsClient.Tests.ps1
Normal file
56
Modules/VMware.vSphere.SsoAdmin/src/test/LsClient.Tests.ps1
Normal file
@@ -0,0 +1,56 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$VcAddress,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$User,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Password
|
||||
)
|
||||
|
||||
# Import Vmware.vSphere.SsoAdmin Module
|
||||
$modulePath = Join-Path (Split-Path $PSScriptRoot | Split-Path) "VMware.vSphere.SsoAdmin.psd1"
|
||||
Import-Module $modulePath
|
||||
|
||||
$script:lsClient = $null
|
||||
|
||||
Describe "Lookup Service Client Integration Tests" {
|
||||
Context "Retrieval of Service API Url" {
|
||||
BeforeAll {
|
||||
## Create LsClient
|
||||
$skipCertificateCheckValidator = New-Object `
|
||||
'VMware.vSphere.SsoAdmin.Utils.AcceptAllX509CertificateValidator'
|
||||
|
||||
$script:lsClient = New-Object `
|
||||
'VMware.vSphere.LsClient.LookupServiceClient' `
|
||||
-ArgumentList @($VCAddress, $skipCertificateCheckValidator)
|
||||
|
||||
}
|
||||
|
||||
It 'Gets SsoAdmin API Url' {
|
||||
# Act
|
||||
$actual = $script:lsClient.GetSsoAdminEndpointUri()
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.ToString().StartsWith("https://$VCAddress/sso-adminserver/sdk/") | Should Be $true
|
||||
}
|
||||
|
||||
It 'Gets STS API Url' {
|
||||
# Act
|
||||
$actual = $script:lsClient.GetStsEndpointUri()
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.ToString().StartsWith("https://$VCAddress/sts/STSService") | Should Be $true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$VcAddress,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$User,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Password
|
||||
)
|
||||
|
||||
# Import Vmware.vSphere.SsoAdmin Module
|
||||
$modulePath = Join-Path (Split-Path $PSScriptRoot | Split-Path) "VMware.vSphere.SsoAdmin.psd1"
|
||||
Import-Module $modulePath
|
||||
|
||||
Describe "PasswordPolicy Tests" {
|
||||
BeforeEach {
|
||||
Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
$connectionsToCleanup = $global:DefaultSsoAdminServers.ToArray()
|
||||
foreach ($connection in $connectionsToCleanup) {
|
||||
Disconnect-SsoAdminServer -Server $connection
|
||||
}
|
||||
}
|
||||
|
||||
Context "Get-SsoPasswordPolicy" {
|
||||
It 'Gets password policy' {
|
||||
# Act
|
||||
$actual = Get-SsoPasswordPolicy
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
}
|
||||
}
|
||||
|
||||
Context "Set-SsoPasswordPolicy" {
|
||||
It 'Updates password policy MaxLength and PasswordLifetimeDays' {
|
||||
# Arrange
|
||||
$passwordPolicyToUpdate = Get-SsoPasswordPolicy
|
||||
$expectedMaxLength = 17
|
||||
$expectedPasswordLifetimeDays = 77
|
||||
|
||||
# Act
|
||||
$actual = Set-SsoPasswordPolicy `
|
||||
-PasswordPolicy $passwordPolicyToUpdate `
|
||||
-MaxLength $expectedMaxLength `
|
||||
-PasswordLifetimeDays $expectedPasswordLifetimeDays
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.MaxLength | Should Be $expectedMaxLength
|
||||
$actual.PasswordLifetimeDays | Should Be $expectedPasswordLifetimeDays
|
||||
$actual.Description | Should Be $passwordPolicyToUpdate.Description
|
||||
$actual.ProhibitedPreviousPasswordsCount | Should Be $passwordPolicyToUpdate.ProhibitedPreviousPasswordsCount
|
||||
$actual.MinLength | Should Be $passwordPolicyToUpdate.MinLength
|
||||
$actual.MaxIdenticalAdjacentCharacters | Should Be $passwordPolicyToUpdate.MaxIdenticalAdjacentCharacters
|
||||
$actual.MinNumericCount | Should Be $passwordPolicyToUpdate.MinNumericCount
|
||||
$actual.MinSpecialCharCount | Should Be $passwordPolicyToUpdate.MinSpecialCharCount
|
||||
$actual.MinAlphabeticCount | Should Be $passwordPolicyToUpdate.MinAlphabeticCount
|
||||
$actual.MinUppercaseCount | Should Be $passwordPolicyToUpdate.MinUppercaseCount
|
||||
$actual.MinLowercaseCount | Should Be $passwordPolicyToUpdate.MinLowercaseCount
|
||||
|
||||
# Cleanup
|
||||
$passwordPolicyToUpdate | Set-SsoPasswordPolicy
|
||||
}
|
||||
|
||||
It 'Updates password policy Description and MinUppercaseCount' {
|
||||
# Arrange
|
||||
$passwordPolicyToUpdate = Get-SsoPasswordPolicy
|
||||
$expectedMinUppercaseCount = 0
|
||||
$expectedDescription = "Test Description"
|
||||
|
||||
# Act
|
||||
$actual = $passwordPolicyToUpdate | Set-SsoPasswordPolicy `
|
||||
-Description $expectedDescription `
|
||||
-MinUppercaseCount $expectedMinUppercaseCount
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.Description | Should Be $expectedDescription
|
||||
$actual.MinUppercaseCount | Should Be $expectedMinUppercaseCount
|
||||
$actual.MaxLength | Should Be $passwordPolicyToUpdate.MaxLength
|
||||
$actual.PasswordLifetimeDays | Should Be $passwordPolicyToUpdate.PasswordLifetimeDays
|
||||
$actual.ProhibitedPreviousPasswordsCount | Should Be $passwordPolicyToUpdate.ProhibitedPreviousPasswordsCount
|
||||
$actual.MinLength | Should Be $passwordPolicyToUpdate.MinLength
|
||||
$actual.MaxIdenticalAdjacentCharacters | Should Be $passwordPolicyToUpdate.MaxIdenticalAdjacentCharacters
|
||||
$actual.MinNumericCount | Should Be $passwordPolicyToUpdate.MinNumericCount
|
||||
$actual.MinSpecialCharCount | Should Be $passwordPolicyToUpdate.MinSpecialCharCount
|
||||
$actual.MinAlphabeticCount | Should Be $passwordPolicyToUpdate.MinAlphabeticCount
|
||||
$actual.MinLowercaseCount | Should Be $passwordPolicyToUpdate.MinLowercaseCount
|
||||
|
||||
# Cleanup
|
||||
$passwordPolicyToUpdate | Set-SsoPasswordPolicy
|
||||
}
|
||||
}
|
||||
}
|
||||
418
Modules/VMware.vSphere.SsoAdmin/src/test/PersonUser.Tests.ps1
Normal file
418
Modules/VMware.vSphere.SsoAdmin/src/test/PersonUser.Tests.ps1
Normal file
@@ -0,0 +1,418 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$VcAddress,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$User,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Password
|
||||
)
|
||||
|
||||
# Import Vmware.vSphere.SsoAdmin Module
|
||||
$modulePath = Join-Path (Split-Path $PSScriptRoot | Split-Path) "VMware.vSphere.SsoAdmin.psd1"
|
||||
Import-Module $modulePath
|
||||
|
||||
Describe "PersonUser Tests" {
|
||||
BeforeEach {
|
||||
$script:usersToCleanup = @()
|
||||
}
|
||||
AfterEach {
|
||||
foreach ($personUser in $script:usersToCleanup) {
|
||||
Remove-SsoPersonUser -User $personUser
|
||||
}
|
||||
|
||||
$connectionsToCleanup = $global:DefaultSsoAdminServers.ToArray()
|
||||
foreach ($connection in $connectionsToCleanup) {
|
||||
Disconnect-SsoAdminServer -Server $connection
|
||||
}
|
||||
}
|
||||
|
||||
Context "New-SsoPersonUser" {
|
||||
It 'Creates person user with details' {
|
||||
# Arrange
|
||||
$expectedUserName = "TestPersonUser1"
|
||||
$expectedPassword = '$tr0NG_TestPa$$w0rd'
|
||||
$expectedDescription = "Test Description"
|
||||
$expectedEmailAddress = "testuser@testdomain.com"
|
||||
$expectedFirstName = "Test"
|
||||
$expectedLastName = "User"
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
# Act
|
||||
$actual = New-SsoPersonUser `
|
||||
-Server $connection `
|
||||
-UserName $expectedUserName `
|
||||
-Password $expectedPassword `
|
||||
-Description $expectedDescription `
|
||||
-EmailAddress $expectedEmailAddress `
|
||||
-FirstName $expectedFirstName `
|
||||
-LastName $expectedLastName
|
||||
|
||||
$script:usersToCleanup += $actual
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.GetType().FullName | Should Be 'VMware.vSphere.SsoAdminClient.DataTypes.PersonUser'
|
||||
$actual.Name | Should Be $expectedUserName
|
||||
$actual.Domain | Should Not Be $null
|
||||
$actual.Description | Should Be $expectedDescription
|
||||
$actual.FirstName | Should Be $expectedFirstName
|
||||
$actual.LastName | Should Be $expectedLastName
|
||||
$actual.EmailAddress | Should Be $expectedEmailAddress
|
||||
}
|
||||
|
||||
It 'Creates person user without details' {
|
||||
# Arrange
|
||||
$expectedUserName = "TestPersonUser2"
|
||||
$expectedPassword = '$tr0NG_TestPa$$w0rd'
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
# Act
|
||||
$actual = New-SsoPersonUser `
|
||||
-Server $connection `
|
||||
-UserName $expectedUserName `
|
||||
-Password $expectedPassword
|
||||
|
||||
$script:usersToCleanup += $actual
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.GetType().FullName | Should Be 'VMware.vSphere.SsoAdminClient.DataTypes.PersonUser'
|
||||
$actual.Name | Should Be $expectedUserName
|
||||
$actual.Domain | Should Not Be $null
|
||||
$actual.Description | Should Be $null
|
||||
$actual.FirstName | Should Be $null
|
||||
$actual.LastName | Should Be $null
|
||||
$actual.EmailAddress | Should Be $null
|
||||
}
|
||||
}
|
||||
|
||||
Context "Get-SsoPersonUser" {
|
||||
It 'Gets person users without filters' {
|
||||
# Arrange
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
# Act
|
||||
$actual = Get-SsoPersonUser
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.Count | Should BeGreaterThan 0
|
||||
$actual[0].Name | Should Not Be $null
|
||||
$actual[0].Domain | Should Be 'localos'
|
||||
}
|
||||
|
||||
It 'Gets person users by name (exact match) and domain filters' {
|
||||
# Arrange
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$expectedUserName = "TestPersonUser3"
|
||||
$secondUserName = "TestPersonUser4"
|
||||
$password = '$tr0NG_TestPa$$w0rd'
|
||||
|
||||
$personUserToSearch = New-SsoPersonUser `
|
||||
-UserName $expectedUserName `
|
||||
-Password $password `
|
||||
-Server $connection
|
||||
$script:usersToCleanup += $personUserToSearch
|
||||
|
||||
$secondPersonUserToSearch = New-SsoPersonUser `
|
||||
-UserName $secondUserName `
|
||||
-Password $password `
|
||||
-Server $connection
|
||||
$script:usersToCleanup += $secondPersonUserToSearch
|
||||
|
||||
# Act
|
||||
$actual = Get-SsoPersonUser `
|
||||
-Name $expectedUserName `
|
||||
-Domain $personUserToSearch.Domain `
|
||||
-Server $connection
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.Name | Should Be $expectedUserName
|
||||
$actual.Domain | Should Not Be $null
|
||||
$actual.Domain | Should Be $personUserToSearch.Domain
|
||||
}
|
||||
|
||||
It 'Gets person users by name (* wildcard match) and domain filters' {
|
||||
# Arrange
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$expectedUserName = "TestPersonUser3"
|
||||
$secondUserName = "TestPersonUser4"
|
||||
$password = '$tr0NG_TestPa$$w0rd'
|
||||
|
||||
$personUserToSearch = New-SsoPersonUser `
|
||||
-UserName $expectedUserName `
|
||||
-Password $password `
|
||||
-Server $connection
|
||||
$script:usersToCleanup += $personUserToSearch
|
||||
|
||||
$secondPersonUserToSearch = New-SsoPersonUser `
|
||||
-UserName $secondUserName `
|
||||
-Password $password `
|
||||
-Server $connection
|
||||
$script:usersToCleanup += $secondPersonUserToSearch
|
||||
|
||||
# Act
|
||||
$actual = Get-SsoPersonUser `
|
||||
-Name "Test*" `
|
||||
-Domain $personUserToSearch.Domain `
|
||||
-Server $connection
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.Count | Should Be 2
|
||||
$actual.Name | Should Contain $expectedUserName
|
||||
$actual.Name | Should Contain $secondUserName
|
||||
}
|
||||
|
||||
It 'Gets person users by name (? wildcard match) and domain filters' {
|
||||
# Arrange
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$expectedUserName = "TestPersonUser3"
|
||||
$secondUserName = "TestPersonUser4"
|
||||
$password = '$tr0NG_TestPa$$w0rd'
|
||||
|
||||
$personUserToSearch = New-SsoPersonUser `
|
||||
-UserName $expectedUserName `
|
||||
-Password $password `
|
||||
-Server $connection
|
||||
$script:usersToCleanup += $personUserToSearch
|
||||
|
||||
$secondPersonUserToSearch = New-SsoPersonUser `
|
||||
-UserName $secondUserName `
|
||||
-Password $password `
|
||||
-Server $connection
|
||||
$script:usersToCleanup += $secondPersonUserToSearch
|
||||
|
||||
# Act
|
||||
$actual = Get-SsoPersonUser `
|
||||
-Name "TestPersonUser?" `
|
||||
-Domain $personUserToSearch.Domain `
|
||||
-Server $connection
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.Count | Should Be 2
|
||||
$actual.Name | Should Contain $expectedUserName
|
||||
$actual.Name | Should Contain $secondUserName
|
||||
}
|
||||
|
||||
It 'Gets person users by unexisting name does not return' {
|
||||
# Arrange
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$expectedUserName = "TestPersonUser3"
|
||||
$password = '$tr0NG_TestPa$$w0rd'
|
||||
|
||||
$personUserToSearch = New-SsoPersonUser `
|
||||
-UserName $expectedUserName `
|
||||
-Password $password `
|
||||
-Server $connection
|
||||
$script:usersToCleanup += $personUserToSearch
|
||||
|
||||
|
||||
# Act
|
||||
$actual = Get-SsoPersonUser `
|
||||
-Name "TestPersonUser" `
|
||||
-Domain $personUserToSearch.Domain `
|
||||
-Server $connection
|
||||
|
||||
# Assert
|
||||
$actual | Should Be $null
|
||||
}
|
||||
}
|
||||
|
||||
Context "Set-SsoPersonUser" {
|
||||
It 'Adds person user to group' {
|
||||
# Arrange
|
||||
$userName = "TestAddGroupPersonUserName"
|
||||
$userPassword = '$tr0NG_TestPa$$w0rd'
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$personUserToUpdate = New-SsoPersonUser `
|
||||
-UserName $userName `
|
||||
-Password $userPassword `
|
||||
-Server $connection
|
||||
|
||||
$script:usersToCleanup += $personUserToUpdate
|
||||
|
||||
$groupUserToBeAddedTo = Get-SsoGroup `
|
||||
-Name 'Administrators' `
|
||||
-Domain $personUserToUpdate.Domain `
|
||||
-Server $connection
|
||||
|
||||
# Act
|
||||
$actual = Set-SsoPersonUser `
|
||||
-User $personUserToUpdate `
|
||||
-Group $groupUserToBeAddedTo `
|
||||
-Add
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
}
|
||||
|
||||
It 'Removes person user from group' {
|
||||
# Arrange
|
||||
$userName = "TestRemoveGroupPersonUserName"
|
||||
$userPassword = '$tr0NG_TestPa$$w0rd'
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$personUserToUpdate = New-SsoPersonUser `
|
||||
-UserName $userName `
|
||||
-Password $userPassword `
|
||||
-Server $connection
|
||||
|
||||
$script:usersToCleanup += $personUserToUpdate
|
||||
|
||||
$groupToBeUsed = Get-SsoGroup `
|
||||
-Name 'Administrators' `
|
||||
-Domain $personUserToUpdate.Domain `
|
||||
-Server $connection
|
||||
|
||||
Set-SsoPersonUser `
|
||||
-User $personUserToUpdate `
|
||||
-Group $groupToBeUsed `
|
||||
-Add
|
||||
|
||||
# Act
|
||||
$actual = Set-SsoPersonUser `
|
||||
-User $personUserToUpdate `
|
||||
-Group $groupToBeUsed `
|
||||
-Remove
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
}
|
||||
|
||||
It 'Resets person user password' {
|
||||
# Arrange
|
||||
$userName = "TestResetPassPersonUserName"
|
||||
$userPassword = '$tr0NG_TestPa$$w0rd'
|
||||
$newPassword = 'Update_TestPa$$w0rd'
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$personUserToUpdate = New-SsoPersonUser `
|
||||
-UserName $userName `
|
||||
-Password $userPassword `
|
||||
-Server $connection
|
||||
|
||||
$script:usersToCleanup += $personUserToUpdate
|
||||
|
||||
# Act
|
||||
$actual = Set-SsoPersonUser `
|
||||
-User $personUserToUpdate `
|
||||
-NewPassword $newPassword
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
}
|
||||
|
||||
It 'Unlocks not locked person user' {
|
||||
# Arrange
|
||||
$userName = "TestResetPassPersonUserName"
|
||||
$userPassword = '$tr0NG_TestPa$$w0rd'
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
$personUserToUpdate = New-SsoPersonUser `
|
||||
-UserName $userName `
|
||||
-Password $userPassword `
|
||||
-Server $connection
|
||||
|
||||
$script:usersToCleanup += $personUserToUpdate
|
||||
|
||||
# Act
|
||||
$actual = Set-SsoPersonUser `
|
||||
-User $personUserToUpdate `
|
||||
-Unlock
|
||||
|
||||
# Assert
|
||||
$actual | Should Be $null
|
||||
}
|
||||
}
|
||||
|
||||
Context "Remove-SsoPersonUser" {
|
||||
It 'Removes person user' {
|
||||
# Arrange
|
||||
$userName = "TestPersonUser4"
|
||||
$userPassword = '$tr0NG_TestPa$$w0rd'
|
||||
$connection = Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
|
||||
|
||||
$personUserToRemove = New-SsoPersonUser `
|
||||
-UserName $userName `
|
||||
-Password $userPassword `
|
||||
-Server $connection
|
||||
|
||||
# Act
|
||||
Remove-SsoPersonUser -User $personUserToRemove
|
||||
|
||||
# Assert
|
||||
$personUserToRemove | Should Not Be $null
|
||||
$userFromServer = Get-SsoPersonUser `
|
||||
-Name $personUserToRemove.Name `
|
||||
-Domain $personUserToRemove.Domain `
|
||||
-Server $connection
|
||||
$userFromServer | Should Be $null
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Modules/VMware.vSphere.SsoAdmin/src/test/RunTests.ps1
Normal file
36
Modules/VMware.vSphere.SsoAdmin/src/test/RunTests.ps1
Normal file
@@ -0,0 +1,36 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$VcAddress,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$User,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Password
|
||||
)
|
||||
|
||||
function Test-PesterIsAvailable() {
|
||||
$pesterModule = Get-Module Pester -List
|
||||
if ($pesterModule -eq $null) {
|
||||
throw "Pester Module is not available"
|
||||
}
|
||||
}
|
||||
|
||||
Test-PesterIsAvailable
|
||||
|
||||
Invoke-Pester `
|
||||
-Script @{
|
||||
Path = $PSScriptRoot
|
||||
Parameters = @{
|
||||
VcAddress = $VcAddress
|
||||
User = $User
|
||||
Password = $Password
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
# **************************************************************************
|
||||
# Copyright 2020 VMware, Inc.
|
||||
# **************************************************************************
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$VcAddress,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$User,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Password
|
||||
)
|
||||
|
||||
# Import Vmware.vSphere.SsoAdmin Module
|
||||
$modulePath = Join-Path (Split-Path $PSScriptRoot | Split-Path) "VMware.vSphere.SsoAdmin.psd1"
|
||||
Import-Module $modulePath
|
||||
|
||||
Describe "TokenLifetime Tests" {
|
||||
BeforeEach {
|
||||
Connect-SsoAdminServer `
|
||||
-Server $VcAddress `
|
||||
-User $User `
|
||||
-Password $Password `
|
||||
-SkipCertificateCheck
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
$connectionsToCleanup = $global:DefaultSsoAdminServers.ToArray()
|
||||
foreach ($connection in $connectionsToCleanup) {
|
||||
Disconnect-SsoAdminServer -Server $connection
|
||||
}
|
||||
}
|
||||
|
||||
Context "Get-SsoTokenLifetime" {
|
||||
It 'Gets token lifetime settings' {
|
||||
# Act
|
||||
$actual = Get-SsoTokenLifetime
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.MaxHoKTokenLifetime | Should BeGreaterThan 0
|
||||
$actual.MaxBearerTokenLifetime | Should BeGreaterThan 0
|
||||
}
|
||||
}
|
||||
|
||||
Context "Set-SsoTokenLifetime" {
|
||||
It 'Updates MaxHoKTokenLifetime and MaxBearerTokenLifetime' {
|
||||
# Arrange
|
||||
$tokenLifetimeToUpdate = Get-SsoTokenLifetime
|
||||
$expectedMaxHoKTokenLifetime = 60
|
||||
$expectedMaxBearerTokenLifetime = 30
|
||||
|
||||
# Act
|
||||
$actual = Set-SsoTokenLifetime `
|
||||
-TokenLifetime $tokenLifetimeToUpdate `
|
||||
-MaxHoKTokenLifetime $expectedMaxHoKTokenLifetime `
|
||||
-MaxBearerTokenLifetime $expectedMaxBearerTokenLifetime
|
||||
|
||||
# Assert
|
||||
$actual | Should Not Be $null
|
||||
$actual.MaxHoKTokenLifetime | Should Be $expectedMaxHoKTokenLifetime
|
||||
$actual.MaxBearerTokenLifetime | Should Be $expectedMaxBearerTokenLifetime
|
||||
|
||||
# Cleanup
|
||||
$tokenLifetimeToUpdate | Set-SsoTokenLifetime `
|
||||
-MaxHoKTokenLifetime $tokenLifetimeToUpdate.MaxHoKTokenLifetime `
|
||||
-MaxBearerTokenLifetime $tokenLifetimeToUpdate.MaxBearerTokenLifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user