Skip to content

Commit

Permalink
Copy Directory from AzureTenant and Type from AzureEnvironment in De…
Browse files Browse the repository at this point in the history
…epCopy of Azure Context (#402)

* Define and implement DeepCloneable interface for Azure* class such as AzureContext

1. Define and implementation `IDeepCloneable` interface
2. Remove unused codes in `DefaultProfile`

* Address the review comments

* Address review comments
  • Loading branch information
msJinLei authored Aug 16, 2023
1 parent 9b5f8b9 commit 935126b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 56 deletions.
15 changes: 12 additions & 3 deletions src/Authentication.Abstractions.Test/ContextUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,18 @@ public void TestDeepCopy()
IAzureAccount account = new AzureAccount()
{
Id = "[email protected]",
Type = "User"
Type = AzureAccount.AccountType.User
};

IAzureEnvironment environment = new AzureEnvironment()
{
Name = "my environment"
Name = "my environment",
Type = AzureEnvironment.TypeDiscovered
};
IAzureTenant tenant = new AzureTenant()
{
Id = "DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD"
Id = "DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD",
Directory = SubHomeTenant
};
IAzureContext original = new AzureContext(subscription, account, environment, tenant);
const string PropertyKey = "customPropertyKey";
Expand All @@ -68,6 +70,13 @@ public void TestDeepCopy()
// custom property
Assert.Equal(SubHomeTenant, clone.Subscription.GetHomeTenant());
Assert.Equal(PropertyValue, clone.GetProperty(PropertyKey));

// implementation specific attributes
Assert.Equal(((AzureEnvironment)original.Environment).Type, ((AzureEnvironment)clone.Environment).Type);
Assert.Equal(((AzureTenant)original.Tenant).Directory, ((AzureTenant)clone.Tenant).Directory);

//tokenCache checking
Assert.Null(clone.TokenCache.CacheData);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ public static IAzureContext DeepCopy(this IAzureContext context)
deepCopy.Tenant.CopyFrom(context.Tenant);
deepCopy.Subscription.CopyFrom(context.Subscription);
deepCopy.Environment.CopyFrom(context.Environment);

//TODO:Whenever to introduce more properties that needs to be copied here, extract the logic to a new method.
if (context.Tenant is AzureTenant azureTenant)
{
((AzureTenant)deepCopy.Tenant).Directory = azureTenant.Directory;
}
if (context.Environment is AzureEnvironment azureEnvironment)
{
((AzureEnvironment)deepCopy.Environment).Type = azureEnvironment.Type;
}
deepCopy.CopyPropertiesFrom(context);
return deepCopy;
}
Expand Down
57 changes: 4 additions & 53 deletions src/ResourceManager/Version2016_09_01/AzureRMCmdlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,59 +86,7 @@ public IAzureContextContainer DefaultProfile
set
{
_profile = value;
/* If the profile is from customer setting, the ServicePrincipalSecret and CertificatePassword
* which is required to get access token is always removed.
* Try to recover ServicePrincipalSecret and CertificatePassword from the buildin profile.
*/
if (null != _profile && null != AzureRmProfileProvider.Instance.Profile.Accounts)
{
var accountMap = CreateAccountMap(AzureRmProfileProvider.Instance.Profile.Accounts);
foreach (var currentAccount in _profile.Accounts.Where(p => null != p?.Id))
{
if (accountMap.TryGetValue(currentAccount.Id, out IList<IAzureAccount> accList))
{
foreach (var acc in accList)
{
if (currentAccount.GetTenants().All(tId => acc.GetTenants().Contains(tId)))
{
MergeProperty(currentAccount, acc, AzureAccount.Property.ServicePrincipalSecret);
MergeProperty(currentAccount, acc, AzureAccount.Property.CertificatePassword);
break;
}
}
}
}
}
}
}

private static Dictionary<string, IList<IAzureAccount>> CreateAccountMap(IEnumerable<IAzureAccount> accounts)
{
var accountMap = new Dictionary<string, IList<IAzureAccount>>();
foreach (var acc in accounts.Where(acc => null != acc?.Id && (null != acc.GetProperty(AzureAccount.Property.ServicePrincipalSecret)
|| null != acc.GetProperty(AzureAccount.Property.CertificatePassword))))
{
if (!accountMap.ContainsKey(acc.Id))
{
accountMap[acc.Id] = new List<IAzureAccount>();
}
accountMap[acc.Id].Add(acc);
}
return accountMap;
}

private static bool MergeProperty(IExtensibleModel dest, IExtensibleModel src, string propertyName)
{
if (string.IsNullOrEmpty(dest.GetProperty(propertyName)))
{
var propertyValue = src.GetProperty(propertyName);
if (!string.IsNullOrEmpty(propertyValue))
{
dest.SetProperty(propertyName, propertyValue);
return true;
}
}
return false;
}

private IAzureContextContainer GetDefaultProfile()
Expand Down Expand Up @@ -174,7 +122,10 @@ private IAzureContextContainer CloneProfileAndModifyContext()
}
profile.DefaultContext = profile.DefaultContext.DeepCopy();
profile.DefaultContext.Subscription.CopyFrom(matchingSub);
profile.DefaultContext.Tenant.Id = matchingSub.GetTenant();
profile.DefaultContext.Tenant = new AzureTenant()
{
Id = matchingSub.GetTenant()
};
var matchingUser = profile.Accounts.FirstOrDefault(account => account.Id.Equals(matchingSub.GetAccount()));
if (matchingUser != null)
{
Expand Down

0 comments on commit 935126b

Please sign in to comment.