diff --git a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient.Tests/IntegrationTests.cs b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient.Tests/IntegrationTests.cs index 04f34a2..127587c 100644 --- a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient.Tests/IntegrationTests.cs +++ b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient.Tests/IntegrationTests.cs @@ -1,14 +1,16 @@ 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 = ""; - private string _user = ""; - private string _rawPassword = ""; + private string _vc = ""; + private string _user = ""; + private string _rawPassword = ""; private SecureString _password; [SetUp] public void Setup() { @@ -49,5 +51,33 @@ namespace VMware.vSphere.SsoAdminClient.Tests 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); + } } } \ No newline at end of file diff --git a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/Principal.cs b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/PersonUser.cs similarity index 96% rename from Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/Principal.cs rename to Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/PersonUser.cs index 12bd5d8..87c06da 100644 --- a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/Principal.cs +++ b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/PersonUser.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace VMware.vSphere.SsoAdminClient.DataTypes { - public class Principal + public class PersonUser { public string Name { get; set; } public string Domain { get; set; } diff --git a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/SsoAdminServer.cs b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/SsoAdminServer.cs new file mode 100644 index 0000000..07dd6de --- /dev/null +++ b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/DataTypes/SsoAdminServer.cs @@ -0,0 +1,68 @@ +// ************************************************************************** +// Copyright (c) VMware, Inc. All rights reserved. -- VMware Confidential. +// ************************************************************************** + +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 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; + } + } +} diff --git a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/SsoAdminClient.cs b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/SsoAdminClient.cs index 081a8f5..74dd890 100644 --- a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/SsoAdminClient.cs +++ b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/SsoAdminClient.cs @@ -22,7 +22,6 @@ namespace VMware.vSphere.SsoAdminClient { private const int WEB_OPERATION_TIMEOUT_SECONDS = 30; - private string _server; private SsoPortTypeClient _ssoAdminBindingClient; private UserPassSecurityContext _securityContext; @@ -31,7 +30,6 @@ namespace VMware.vSphere.SsoAdminClient if (user == null) throw new ArgumentNullException(nameof(user)); if (password == null) throw new ArgumentNullException(nameof(password)); - _server = hostname; var lsClient = new LookupServiceClient(hostname, serverCertificateValidator); // Create STS Client @@ -40,6 +38,8 @@ namespace VMware.vSphere.SsoAdminClient // 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()); @@ -121,7 +121,10 @@ namespace VMware.vSphere.SsoAdminClient #region Public interface - public Principal CreateLocalUser( + public Uri ServiceUri { get; } + public string User { get; } + + public PersonUser CreateLocalUser( string userName, string password, string description = null, @@ -153,7 +156,7 @@ namespace VMware.vSphere.SsoAdminClient return GetLocalUsers(ssoPrincipalId.name, ssoPrincipalId.domain, authorizedInvocationContext); } - private Principal GetLocalUsers(string userName, string domain, WsSecurityContext wsSecurityContext) { + private PersonUser GetLocalUsers(string userName, string domain, WsSecurityContext wsSecurityContext) { // Invoke SSO Admin FindPersonUserAsync operation var personUser = wsSecurityContext. InvokeOperation(() => @@ -166,7 +169,7 @@ namespace VMware.vSphere.SsoAdminClient name = userName, domain = domain })).Result; - return new Principal { + return new PersonUser { Name = personUser.id.name, Domain = personUser.id.domain, Description = personUser.details.description, @@ -176,7 +179,7 @@ namespace VMware.vSphere.SsoAdminClient }; } - public IEnumerable GetAllLocalUsers() { + public IEnumerable GetLocalUsers(string searchString, string domain) { // Create Authorization Invocation Context var authorizedInvocationContext = CreateAuthorizedInvocationContext(); @@ -188,24 +191,30 @@ namespace VMware.vSphere.SsoAdminClient new ManagedObjectReference { type = "SsoAdminPrincipalDiscoveryService", Value = "principalDiscoveryService" - }, - new SsoAdminPrincipalDiscoveryServiceSearchCriteria (), + }, + new SsoAdminPrincipalDiscoveryServiceSearchCriteria { + searchString = searchString, + domain = domain + }, int.MaxValue)).Result.returnval; - foreach (var personUser in personUsers) { - yield return new Principal { - Name = personUser.id.name, - Domain = personUser.id.domain, - Description = personUser.details.description, - FirstName = personUser.details.firstName, - LastName = personUser.details.lastName, - EmailAddress = personUser.details.emailAddress - }; + if (personUsers != null) { + foreach (var personUser in personUsers) { + yield return new PersonUser { + 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( - Principal principal) { + PersonUser principal) { // Create Authorization Invocation Context var authorizedInvocationContext = diff --git a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/UserPassSecurityContext.cs b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/UserPassSecurityContext.cs index 6251081..6249c61 100644 --- a/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/UserPassSecurityContext.cs +++ b/Modules/VMware.vSphere.SsoAdmin/src/VMware.vSphere.SsoAdmin.Client/VMware.vSphere.SsoAdminClient/UserPassSecurityContext.cs @@ -19,6 +19,7 @@ namespace VMware.vSphere.SsoAdminClient private string _user; private SecureString _password; private VmwareSecruityTokenService _stsClient; + private SamlSecurityToken _validToken; public UserPassSecurityContext( string user, SecureString password, @@ -39,10 +40,18 @@ namespace VMware.vSphere.SsoAdminClient _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() { - return _stsClient.IssueBearerTokenByUserCredential( - _user, - _password).RawToken; + RenewIfNeeded(); + return _validToken.RawToken; } } }