Skip to content

Commit eff4ea6

Browse files
committed
azrepos: add tests of MID and SP get credential
Add tests of the `GetCredentialAsync` method on the `AzureReposHostProvider` using managed identity and service principal.
1 parent aafbda4 commit eff4ea6

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,102 @@ public async Task AzureReposProvider_GetCredentialAsync_PatMode_ExistingPat_Retu
511511
Assert.Equal(personalAccessToken, credential.Password);
512512
}
513513

514+
[Fact]
515+
public async Task AzureReposProvider_GetCredentialAsync_ManagedIdentity_ReturnsManagedIdCredential()
516+
{
517+
var input = new InputArguments(new Dictionary<string, string>
518+
{
519+
["protocol"] = "https",
520+
["host"] = "dev.azure.com",
521+
["path"] = "org/proj/_git/repo"
522+
});
523+
524+
const string accessToken = "MANAGED-IDENTITY-TOKEN";
525+
const string managedIdentity = "MANAGED-IDENTITY";
526+
527+
var context = new TestCommandContext
528+
{
529+
Environment =
530+
{
531+
Variables =
532+
{
533+
[AzureDevOpsConstants.EnvironmentVariables.ManagedIdentity] = managedIdentity
534+
}
535+
}
536+
};
537+
538+
var azDevOps = Mock.Of<IAzureDevOpsRestApi>();
539+
var authorityCache = Mock.Of<IAzureDevOpsAuthorityCache>();
540+
var userMgr = Mock.Of<IAzureReposBindingManager>();
541+
var msAuthMock = new Mock<IMicrosoftAuthentication>();
542+
543+
msAuthMock.Setup(x => x.GetTokenForManagedIdentityAsync(It.IsAny<string>(), It.IsAny<string>()))
544+
.ReturnsAsync(new MockMsAuthResult { AccessToken = accessToken });
545+
546+
var provider = new AzureReposHostProvider(context, azDevOps, msAuthMock.Object, authorityCache, userMgr);
547+
548+
ICredential credential = await provider.GetCredentialAsync(input);
549+
550+
Assert.NotNull(credential);
551+
Assert.Equal(managedIdentity, credential.Account);
552+
Assert.Equal(accessToken, credential.Password);
553+
554+
msAuthMock.Verify(
555+
x => x.GetTokenForManagedIdentityAsync(managedIdentity,
556+
AzureDevOpsConstants.AzureDevOpsResourceId), Times.Once);
557+
}
558+
559+
[Fact]
560+
public async Task AzureReposProvider_GetCredentialAsync_ServicePrincipal_ReturnsSPCredential()
561+
{
562+
var input = new InputArguments(new Dictionary<string, string>
563+
{
564+
["protocol"] = "https",
565+
["host"] = "dev.azure.com",
566+
["path"] = "org/proj/_git/repo"
567+
});
568+
569+
const string accessToken = "SP-TOKEN";
570+
const string tenantId = "78B1822F-107D-40A3-A29C-AB68D8066074";
571+
const string clientId = "49B4DC1A-58A8-4EEE-A81B-616A40D0BA64";
572+
const string servicePrincipal = $"{tenantId}/{clientId}";
573+
const string servicePrincipalSecret = "CLIENT-SECRET";
574+
575+
var context = new TestCommandContext
576+
{
577+
Environment =
578+
{
579+
Variables =
580+
{
581+
[AzureDevOpsConstants.EnvironmentVariables.ServicePrincipalId] = servicePrincipal,
582+
[AzureDevOpsConstants.EnvironmentVariables.ServicePrincipalSecret] = servicePrincipalSecret
583+
}
584+
}
585+
};
586+
587+
var azDevOps = Mock.Of<IAzureDevOpsRestApi>();
588+
var authorityCache = Mock.Of<IAzureDevOpsAuthorityCache>();
589+
var userMgr = Mock.Of<IAzureReposBindingManager>();
590+
var msAuthMock = new Mock<IMicrosoftAuthentication>();
591+
592+
msAuthMock.Setup(x =>
593+
x.GetTokenForServicePrincipalAsync(It.IsAny<ServicePrincipalIdentity>(), It.IsAny<string[]>()))
594+
.ReturnsAsync(new MockMsAuthResult { AccessToken = accessToken });
595+
596+
var provider = new AzureReposHostProvider(context, azDevOps, msAuthMock.Object, authorityCache, userMgr);
597+
598+
ICredential credential = await provider.GetCredentialAsync(input);
599+
600+
Assert.NotNull(credential);
601+
Assert.Equal(clientId, credential.Account);
602+
Assert.Equal(accessToken, credential.Password);
603+
604+
msAuthMock.Verify(x => x.GetTokenForServicePrincipalAsync(
605+
It.Is<ServicePrincipalIdentity>(sp => sp.TenantId == tenantId && sp.Id == clientId),
606+
It.Is<string[]>(scopes => scopes.Length == 1 && scopes[0] == AzureDevOpsConstants.AzureDevOpsDefaultScopes[0])),
607+
Times.Once);
608+
}
609+
514610
[Fact]
515611
public async Task AzureReposHostProvider_ConfigureAsync_UseHttpPathSetTrue_DoesNothing()
516612
{

0 commit comments

Comments
 (0)