Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SLVS-1732 Fix SSF-694 #5921

Closed
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace SonarLint.VisualStudio.ConnectedMode.UnitTests.Binding;
public class UnintrusiveBindingControllerTests
{
private static readonly CancellationToken ACancellationToken = CancellationToken.None;
private static readonly BasicAuthCredentials ValidToken = new("TOKEN", new SecureString());
private static readonly UsernameAndPasswordCredentials ValidToken = new("TOKEN", new SecureString());
private static readonly BoundServerProject AnyBoundProject = new("any", "any", new ServerConnection.SonarCloud("any", credentials: ValidToken));
private IActiveSolutionChangedHandler activeSolutionChangedHandler;
private IBindingProcess bindingProcess;
Expand Down Expand Up @@ -86,8 +86,8 @@ await sonarQubeService
.Received()
.ConnectAsync(
Arg.Is<ConnectionInformation>(x => x.ServerUri.Equals("https://sonarcloud.io/")
&& x.UserName.Equals(ValidToken.UserName)
&& string.IsNullOrEmpty(x.Password.ToUnsecureString())),
&& ((UsernameAndPasswordCredentials)x.Credentials).UserName.Equals(ValidToken.UserName)
&& string.IsNullOrEmpty(((UsernameAndPasswordCredentials)x.Credentials).Password.ToUnsecureString())),
ACancellationToken);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ public async Task MigrateBindingToServerConnectionIfNeeded_MigrationIsExecutedFo
var boundProjects = bindingPathToBoundProjectDictionary.Values.ToList();
var expectedServerConnectionId = boundProjects[0].ServerUri.ToString();
serverConnectionsRepository.TryGet(expectedServerConnectionId, out _).Returns(true);


await testSubject.MigrateAllBindingsToServerConnectionsIfNeededAsync();

Expand Down Expand Up @@ -215,8 +214,7 @@ private Dictionary<string, BoundSonarQubeProject> CreateTwoBindingPathsToMockedB
{
Dictionary<string, BoundSonarQubeProject> pathToBindings = new()
{
{"bindings/proj1/binding.config", CreateBoundProject("http://server1", "proj1")},
{"bindings/proj2/binding.config", CreateBoundProject("http://server2", "proj2")}
{ "bindings/proj1/binding.config", CreateBoundProject("http://server1", "proj1") }, { "bindings/proj2/binding.config", CreateBoundProject("http://server2", "proj2") }
};
unintrusiveBindingPathProvider.GetBindingPaths().Returns(pathToBindings.Select(kvp => kvp.Key));
foreach (var kvp in pathToBindings)
Expand All @@ -234,7 +232,7 @@ private void MockValidBinding(string bindingPath, BoundSonarQubeProject sonarQub

private static BoundSonarQubeProject CreateBoundProject(string url, string projectKey)
{
return new BoundSonarQubeProject(new Uri(url), projectKey, "projectName", credentials: new BasicAuthCredentials("admin", "admin".ToSecureString()));
return new BoundSonarQubeProject(new Uri(url), projectKey, "projectName", credentials: new UsernameAndPasswordCredentials("admin", "admin".ToSecureString()));
}

private static bool IsExpectedServerConnection(ServerConnection serverConnection, BoundSonarQubeProject boundProject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void MefCtor_CheckIsSingleton()
{
MefTestHelpers.CheckIsSingletonMefComponent<BindingJsonModelConverter>();
}

[TestMethod]
public void ConvertFromModel_ConvertsCorrectly()
{
Expand All @@ -75,10 +75,7 @@ public void ConvertFromModel_ConvertsCorrectly()
[TestMethod]
public void ConvertToModel_SonarCloudConnection_ConvertsCorrectly()
{
var boundServerProject = new BoundServerProject("localBinding", "serverProject", new ServerConnection.SonarCloud("myorg"))
{
Profiles = new Dictionary<Language, ApplicableQualityProfile>()
};
var boundServerProject = new BoundServerProject("localBinding", "serverProject", new ServerConnection.SonarCloud("myorg")) { Profiles = new Dictionary<Language, ApplicableQualityProfile>() };

var bindingModel = testSubject.ConvertToModel(boundServerProject);

Expand All @@ -89,7 +86,7 @@ public void ConvertToModel_SonarCloudConnection_ConvertsCorrectly()
bindingModel.ServerConnectionId.Should().BeSameAs(boundServerProject.ServerConnection.Id);
bindingModel.Profiles.Should().BeSameAs(boundServerProject.Profiles);
}

[TestMethod]
public void ConvertToModel_SonarQubeConnection_ConvertsCorrectly()
{
Expand All @@ -111,7 +108,7 @@ public void ConvertToModel_SonarQubeConnection_ConvertsCorrectly()
[TestMethod]
public void ConvertFromModelToLegacy_ConvertsCorrectly()
{
var credentials = Substitute.For<ICredentials>();
var credentials = Substitute.For<IConnectionCredentials>();
var bindingModel = new BindingJsonModel
{
Organization = new SonarQubeOrganization("org", "my org"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using Microsoft.VisualStudio.LanguageServices.Progression;
using SonarLint.VisualStudio.ConnectedMode.Persistence;
using SonarLint.VisualStudio.Core.Binding;
using SonarLint.VisualStudio.TestInfrastructure;
Expand Down Expand Up @@ -47,8 +48,7 @@ public void BoundSonarQubeProject_CreateConnectionInformation_NoCredentials()

// Assert
conn.ServerUri.Should().Be(input.ServerUri);
conn.UserName.Should().BeNull();
conn.Password.Should().BeNull();
conn.Credentials.Should().BeAssignableTo<INoCredentials>();
conn.Organization.Key.Should().Be("org_key");
conn.Organization.Name.Should().Be("org_name");
}
Expand All @@ -57,7 +57,7 @@ public void BoundSonarQubeProject_CreateConnectionInformation_NoCredentials()
public void BoundSonarQubeProject_CreateConnectionInformation_BasicAuthCredentials()
{
// Arrange
var creds = new BasicAuthCredentials("UserName", "password".ToSecureString());
var creds = new UsernameAndPasswordCredentials("UserName", "password".ToSecureString());
var input = new BoundSonarQubeProject(new Uri("http://server"), "ProjectKey", "projectName", creds,
new SonarQubeOrganization("org_key", "org_name"));

Expand All @@ -66,8 +66,10 @@ public void BoundSonarQubeProject_CreateConnectionInformation_BasicAuthCredentia

// Assert
conn.ServerUri.Should().Be(input.ServerUri);
conn.UserName.Should().Be(creds.UserName);
conn.Password.ToUnsecureString().Should().Be(creds.Password.ToUnsecureString());
var basicAuth = conn.Credentials as UsernameAndPasswordCredentials;
basicAuth.Should().NotBeNull();
basicAuth.UserName.Should().Be(creds.UserName);
basicAuth.Password.ToUnsecureString().Should().Be(creds.Password.ToUnsecureString());
conn.Organization.Key.Should().Be("org_key");
conn.Organization.Name.Should().Be("org_name");
}
Expand All @@ -83,11 +85,10 @@ public void BoundSonarQubeProject_CreateConnectionInformation_NoOrganizationNoAu

// Assert
conn.ServerUri.Should().Be(input.ServerUri);
conn.UserName.Should().BeNull();
conn.Password.Should().BeNull();
conn.Credentials.Should().BeAssignableTo<INoCredentials>();
conn.Organization.Should().BeNull();
}

[TestMethod]
public void BoundServerProject_CreateConnectionInformation_ArgCheck()
{
Expand All @@ -105,26 +106,26 @@ public void BoundServerProject_CreateConnectionInformation_NoCredentials()

// Assert
conn.ServerUri.Should().Be(input.ServerConnection.ServerUri);
conn.UserName.Should().BeNull();
conn.Password.Should().BeNull();
conn.Credentials.Should().BeAssignableTo<INoCredentials>();
conn.Organization.Key.Should().Be("org_key");
}


[TestMethod]
public void BoundServerProject_CreateConnectionInformation_BasicAuthCredentials()
{
// Arrange
var creds = new BasicAuthCredentials("UserName", "password".ToSecureString());
var creds = new UsernameAndPasswordCredentials("UserName", "password".ToSecureString());
var input = new BoundServerProject("solution", "ProjectKey", new ServerConnection.SonarCloud("org_key", credentials: creds));

// Act
ConnectionInformation conn = input.CreateConnectionInformation();

// Assert
conn.ServerUri.Should().Be(input.ServerConnection.ServerUri);
conn.UserName.Should().Be(creds.UserName);
conn.Password.ToUnsecureString().Should().Be(creds.Password.ToUnsecureString());
var basicAuth = conn.Credentials as UsernameAndPasswordCredentials;
basicAuth.Should().NotBeNull();
basicAuth.UserName.Should().Be(creds.UserName);
basicAuth.Password.ToUnsecureString().Should().Be(creds.Password.ToUnsecureString());
conn.Organization.Key.Should().Be("org_key");
}

Expand All @@ -139,8 +140,7 @@ public void BoundServerProject_CreateConnectionInformation_NoOrganizationNoAuth(

// Assert
conn.ServerUri.Should().Be(input.ServerConnection.ServerUri);
conn.UserName.Should().BeNull();
conn.Password.Should().BeNull();
conn.Credentials.Should().BeAssignableTo<INoCredentials>();
conn.Organization.Should().BeNull();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void BoundProject_Serialization()
// Arrange
var serverUri = new Uri("https://finding-nemo.org");
var projectKey = "MyProject Key";
var testSubject = new BoundSonarQubeProject(serverUri, projectKey, "projectName", new BasicAuthCredentials("used", "pwd".ToSecureString()));
var testSubject = new BoundSonarQubeProject(serverUri, projectKey, "projectName", new UsernameAndPasswordCredentials("used", "pwd".ToSecureString()));

// Act (serialize + de-serialize)
string data = JsonHelper.Serialize(testSubject);
Expand All @@ -48,14 +48,14 @@ public void BoundProject_Serialization()
deserialized.ServerUri.Should().Be(testSubject.ServerUri);
deserialized.Credentials.Should().BeNull();
}

[TestMethod]
public void BoundProject_BindingJsonModel_Serialization()
{
// Arrange
var serverUri = new Uri("https://finding-nemo.org");
var projectKey = "MyProject Key";
var testSubject = new BoundSonarQubeProject(serverUri, projectKey, "projectName", new BasicAuthCredentials("used", "pwd".ToSecureString()));
var testSubject = new BoundSonarQubeProject(serverUri, projectKey, "projectName", new UsernameAndPasswordCredentials("used", "pwd".ToSecureString()));

// Act (serialize + de-serialize)
string data = JsonHelper.Serialize(testSubject);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-2024 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using Microsoft.Alm.Authentication;
using SonarLint.VisualStudio.ConnectedMode.Persistence;
using SonarQube.Client.Helpers;
using SonarQube.Client.Models;

namespace SonarLint.VisualStudio.ConnectedMode.UnitTests.Persistence;

[TestClass]
public class CredentialsExtensionMethodsTests
{
[TestMethod]
public void ToCredential_NullCredentials_Throws() => Assert.ThrowsException<NotSupportedException>(() => ((IConnectionCredentials)null).ToCredential());

[TestMethod]
public void ToCredential_UsernameAndPasswordCredentials_ReturnsExpected()
{
var basicCredentials = new UsernameAndPasswordCredentials("user", "pwd".ToSecureString());

var result = basicCredentials.ToCredential();

result.Username.Should().Be(basicCredentials.UserName);
result.Password.Should().Be(basicCredentials.Password.ToUnsecureString());
}

[TestMethod]
public void ToCredential_TokenAuthCredentials_ReturnsExpected()
{
var tokenAuthCredentials = new TokenAuthCredentials("token".ToSecureString());

var result = tokenAuthCredentials.ToCredential();

result.Username.Should().Be(tokenAuthCredentials.Token.ToUnsecureString());
result.Password.Should().Be(string.Empty);
}

[TestMethod]
public void ToICredentials_UsernameIsEmpty_ReturnsUsernameAndPasswordCredentialsWithPasswordAsToken()
{
var credential = new Credential(string.Empty, "token");

var result = credential.ToICredentials();

var basicCredentials = result as UsernameAndPasswordCredentials;
basicCredentials.Should().NotBeNull();
basicCredentials.UserName.Should().Be(credential.Username);
basicCredentials.Password.ToUnsecureString().Should().Be(credential.Password);
}

/// <summary>
/// For backward compatibility
/// </summary>
[TestMethod]
public void ToICredentials_PasswordIsEmpty_ReturnsTokenAuthCredentialsWithUsernameAsToken()
{
var credential = new Credential("token", string.Empty);

var result = credential.ToICredentials();

var tokenAuth = result as TokenAuthCredentials;
tokenAuth.Should().NotBeNull();
tokenAuth.Token.ToUnsecureString().Should().Be(credential.Username);
}

[TestMethod]
public void ToICredentials_PasswordAndUsernameFilled_ReturnsUsernameAndPasswordCredentials()
{
var credential = new Credential("username", "pwd");

var result = credential.ToICredentials();

var basicCredentials = result as UsernameAndPasswordCredentials;
basicCredentials.Should().NotBeNull();
basicCredentials.UserName.Should().Be(credential.Username);
basicCredentials.Password.ToUnsecureString().Should().Be(credential.Password);
}

[TestMethod]
public void ToICredentials_Null_ReturnsNull()
{
var result = ((Credential)null).ToICredentials();

result.Should().BeNull();
}
}
Loading