From a36256af7bde419daff22def54cb086a9c43624c Mon Sep 17 00:00:00 2001 From: Vadim Ponomarev Date: Mon, 4 Jan 2016 14:15:47 -0800 Subject: [PATCH 1/2] Azure RemoteApp: per-app publishing support --- .../Commands.RemoteApp.Test.csproj | 4 +- .../Common/RemoteAppClient.cs | 2 + .../Common/UserObjects.cs | 123 ++++++++++++++++ .../RemoteAppSecurityPrincipals.cs | 136 ++++++++++++++++++ .../Commands.RemoteApp.Test/packages.config | 2 +- .../Collection/Model/CollectionAclLevel.cs | 14 ++ .../Collection/Model/Collections.cs | 1 + .../Collection/SetAzureRemoteAppCollection.cs | 44 ++++++ .../Commands.RemoteApp.csproj | 5 +- ...ndowsAzure.Commands.RemoteApp.dll-help.xml | 91 +++++++++++- .../AddAzureRemoteAppUser.cs | 2 +- .../GetAzureRemoteAppUser.cs | 14 +- .../RemoveAzureRemoteAppUser.cs | 2 +- .../SecurityPrincipals/SecurityPrincipals.cs | 27 +++- .../Commands.RemoteApp/packages.config | 2 +- 15 files changed, 455 insertions(+), 14 deletions(-) create mode 100644 src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/Model/CollectionAclLevel.cs diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj index f56d85124127..fe67d7ed9675 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj @@ -144,8 +144,8 @@ ..\..\..\packages\Microsoft.WindowsAzure.Management.4.1.1\lib\net40\Microsoft.WindowsAzure.Management.dll - - ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.2\lib\net40\Microsoft.WindowsAzure.Management.RemoteApp.dll + + ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.5\lib\net40\Microsoft.WindowsAzure.Management.RemoteApp.dll ..\..\..\packages\Moq.4.2.1402.2112\lib\net40\Moq.dll diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Common/RemoteAppClient.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Common/RemoteAppClient.cs index dd2639c85834..c5e57428435f 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Common/RemoteAppClient.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Common/RemoteAppClient.cs @@ -64,6 +64,8 @@ public abstract class RemoteAppClientTest : SMTestBase protected const string remoteApplication = "Mohoro Test App"; + protected const string appAlias = "9bd99659-9772-4689-af10-7ac72e43c28e"; + protected Action logger { get; private set; } public MockCommandRuntime mockCommandRuntime { get; private set; } diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Common/UserObjects.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Common/UserObjects.cs index 7bb76957b1f3..4d8a5764d1db 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Common/UserObjects.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Common/UserObjects.cs @@ -65,6 +65,46 @@ public static int SetUpDefaultRemoteAppSecurityPrincipals(Mock clientMock, string collectionName, string appAlias, string userName) + { + SecurityPrincipalInfoListResult response = new SecurityPrincipalInfoListResult(); + + response.SecurityPrincipalInfoList = new List() + { + new SecurityPrincipalInfo() + { + SecurityPrincipal = new SecurityPrincipal() + { + Name = userName, + SecurityPrincipalType = PrincipalType.User, + UserIdType = PrincipalProviderType.OrgId, + }, + Status = ConsentStatus.Pending + }, + new SecurityPrincipalInfo() + { + SecurityPrincipal = new SecurityPrincipal() + { + Name = "user2", + SecurityPrincipalType = PrincipalType.User, + UserIdType = PrincipalProviderType.OrgId, + }, + Status = ConsentStatus.Pending + }, + }; + + mockUsersConsents = new List(); + foreach (SecurityPrincipalInfo consent in response.SecurityPrincipalInfoList) + { + mockUsersConsents.Add(new ConsentStatusModel(consent)); + }; + + ISetup> setup = clientMock.Setup(c => c.Principals.ListForAppAsync(collectionName, appAlias, It.IsAny())); + setup.Returns(Task.Factory.StartNew(() => response)); + + return mockUsersConsents.Count; + } + public static int SetUpRemoteAppUserToAdd(Mock clientMock, string collectionName, PrincipalProviderType userIdType, string[] userNames) { SecurityPrincipalOperationsResult response = new SecurityPrincipalOperationsResult() @@ -148,6 +188,89 @@ public static int SetUpDefaultRemoteAppUserToRemove(Mock clientMock, string collectionName, string appAlias, PrincipalProviderType userIdType, string[] userNames) + { + SecurityPrincipalOperationsResult response = new SecurityPrincipalOperationsResult() + { + RequestId = "122-13342", + TrackingId = "2334-323456", + StatusCode = System.Net.HttpStatusCode.Accepted, + Errors = null, + }; + + mockSecurityPrincipalResult = new List() + { + new SecurityPrincipalOperationsResult() + { + RequestId = response.RequestId, + TrackingId = response.TrackingId, + StatusCode = response.StatusCode, + Errors = response.Errors + }, + }; + + SecurityPrincipalList spAdd = new SecurityPrincipalList(); + + foreach (string userName in userNames) + { + SecurityPrincipal mockUser = new SecurityPrincipal() + { + Name = userName, + SecurityPrincipalType = PrincipalType.User, + UserIdType = userIdType, + }; + spAdd.SecurityPrincipals.Add(mockUser); + } + + ISetup> setup = clientMock.Setup(c => c.Principals.AddToAppAsync(collectionName, appAlias, It.IsAny(), It.IsAny())); + setup.Returns(Task.Factory.StartNew(() => response)); + + mockUsers = spAdd.SecurityPrincipals; + + return mockUsers.Count; + } + + public static int SetUpRemoteAppUserToRemoveFromApp(Mock clientMock, string collectionName, string appAlias, PrincipalProviderType userIdType, string[] userNames) + { + SecurityPrincipalOperationsResult response = new SecurityPrincipalOperationsResult() + { + RequestId = "122-13342", + TrackingId = "1348570-182754", + StatusCode = System.Net.HttpStatusCode.Accepted, + Errors = null + }; + mockSecurityPrincipalResult = new List() + { + new SecurityPrincipalOperationsResult() + { + RequestId = response.RequestId, + TrackingId = response.TrackingId, + StatusCode = response.StatusCode, + Errors = response.Errors + }, + }; + + SecurityPrincipalList spRemove = new SecurityPrincipalList(); + + foreach (string userName in userNames) + { + SecurityPrincipal mockUser = new SecurityPrincipal() + { + Name = userName, + SecurityPrincipalType = PrincipalType.User, + UserIdType = userIdType, + }; + spRemove.SecurityPrincipals.Add(mockUser); + } + + ISetup> setup = clientMock.Setup(c => c.Principals.DeleteFromAppAsync(collectionName, appAlias, It.IsAny(), It.IsAny())); + setup.Returns(Task.Factory.StartNew(() => response)); + + mockUsers = spRemove.SecurityPrincipals; + + return mockUsers.Count; + } + public static bool ContainsExpectedServicePrincipalList(IList expectedResult, IList principalList) { bool isIdentical = false; diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/SecurityPrincipals/RemoteAppSecurityPrincipals.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/SecurityPrincipals/RemoteAppSecurityPrincipals.cs index 069a541b0a57..78cc6c825caf 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/SecurityPrincipals/RemoteAppSecurityPrincipals.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/SecurityPrincipals/RemoteAppSecurityPrincipals.cs @@ -71,6 +71,51 @@ public void GetAllUsers() Log("The test for Get-AzureRemoteAppUser with {0} users completed successfully.", countOfExpectedUsers); } + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + public void GetAllUsersForApp() + { + int countOfExpectedUsers = 0; + GetAzureRemoteAppUser MockCmdlet = SetUpTestCommon(); + + // Required parameters for this test + MockCmdlet.CollectionName = collectionName; + MockCmdlet.Alias = appAlias; + + // Setup the environment for testing this cmdlet + MockObject.SetUpDefaultRemoteAppCollectionByName(remoteAppManagementClientMock, collectionName); + countOfExpectedUsers = MockObject.SetUpRemoteAppSecurityPrincipalsForApp(remoteAppManagementClientMock, collectionName, appAlias, userName); + MockCmdlet.ResetPipelines(); + + Log("Calling Get-AzureRemoteAppUser which should have {0} users.", countOfExpectedUsers); + + MockCmdlet.ExecuteCmdlet(); + if (MockCmdlet.runTime().ErrorStream.Count != 0) + { + Assert.True(false, + String.Format("Get-AzureRemoteAppUser returned the following error {0}.", + MockCmdlet.runTime().ErrorStream[0].Exception.Message + ) + ); + } + + List users = MockObject.ConvertList(MockCmdlet.runTime().OutputPipeline); + Assert.NotNull(users); + + Assert.True(users.Count == countOfExpectedUsers, + String.Format("The expected number of users returned {0} does not match the actual {1}.", + countOfExpectedUsers, + users.Count + ) + ); + + Assert.True(MockObject.ContainsExpectedServicePrincipalList(MockObject.mockUsersConsents, users), + "The actual result does not match the expected" + ); + + Log("The test for Get-AzureRemoteAppUser with {0} users completed successfully.", countOfExpectedUsers); + } + [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void GetUsersByName() @@ -206,6 +251,97 @@ public void AddOrgIDUserThatDoesntExist() Log("The test for Add-AzureRemoteAppOrgIDUser successfully added {0} users the new count is {1}.", countOfNewUsers, countOfExistingUsers + countOfNewUsers); } + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + public void AddUsersToApp() + { + int countOfExistingUsers = 0; + int countOfNewUsers = 0; + AddAzureRemoteAppUser MockCmdlet = SetUpTestCommon(); + + // Required parameters for this test + MockCmdlet.CollectionName = collectionName; + MockCmdlet.Alias = appAlias; + MockCmdlet.Type = PrincipalProviderType.OrgId; + MockCmdlet.UserUpn = new string[] + { + "testUser1", + "testUser2", + }; + + // Setup the environment for testing this cmdlet + MockObject.SetUpDefaultRemoteAppCollectionByName(remoteAppManagementClientMock, collectionName); + countOfExistingUsers = MockObject.SetUpDefaultRemoteAppSecurityPrincipals(remoteAppManagementClientMock, collectionName, userName); + countOfNewUsers = MockObject.SetUpRemoteAppUserToAddForApp(remoteAppManagementClientMock, collectionName, appAlias, PrincipalProviderType.OrgId, MockCmdlet.UserUpn); + MockCmdlet.ResetPipelines(); + + Log("Calling Add-AzureRemoteAppOrgIDUser and adding {0} users.", countOfNewUsers); + + MockCmdlet.ExecuteCmdlet(); + if (MockCmdlet.runTime().ErrorStream.Count != 0) + { + Assert.True(false, + String.Format("Add-AzureRemoteAppOrgIDUser returned the following error {0}.", + MockCmdlet.runTime().ErrorStream[0].Exception.Message + ) + ); + } + + List status = MockObject.ConvertList(MockCmdlet.runTime().OutputPipeline); + Assert.NotNull(status); + + Assert.True(MockObject.HasExpectedResults(status, MockObject.ContainsExpectedStatus), + "The actual result does not match the expected." + ); + + Log("The test for Add-AzureRemoteAppOrgIDUser successfully added {0} users the new count is {1}.", countOfNewUsers, countOfExistingUsers + countOfNewUsers); + } + + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + public void RemoveUserThatExistsFromApp() + { + int countOfExistingUsers = 0; + int countOfDeletedUsers = 0; + RemoveAzureRemoteAppUser MockCmdlet = SetUpTestCommon(); + + // Required parameters for this test + MockCmdlet.CollectionName = collectionName; + MockCmdlet.Alias = appAlias; + MockCmdlet.Type = PrincipalProviderType.OrgId; + MockCmdlet.UserUpn = new string[] + { + userName + }; + + // Setup the environment for testing this cmdlet + MockObject.SetUpDefaultRemoteAppCollectionByName(remoteAppManagementClientMock, collectionName); + countOfExistingUsers = MockObject.SetUpDefaultRemoteAppSecurityPrincipals(remoteAppManagementClientMock, collectionName, userName); + countOfDeletedUsers = MockObject.SetUpRemoteAppUserToRemoveFromApp(remoteAppManagementClientMock, collectionName, appAlias, PrincipalProviderType.OrgId, MockCmdlet.UserUpn); + MockCmdlet.ResetPipelines(); + + Log("Calling Remove-AzureRemoteAppOrgIdUser and removing {0} users.", countOfDeletedUsers); + + MockCmdlet.ExecuteCmdlet(); + if (MockCmdlet.runTime().ErrorStream.Count != 0) + { + Assert.True(false, + String.Format("Remove-AzureRemoteAppMSAUser returned the following error {0}.", + MockCmdlet.runTime().ErrorStream[0].Exception.Message + ) + ); + } + + List status = MockObject.ConvertList(MockCmdlet.runTime().OutputPipeline); + Assert.NotNull(status); + + Assert.True(MockObject.HasExpectedResults(status, MockObject.ContainsExpectedStatus), + "The actual result does not match the expected." + ); + + Log("The test for Remove-AzureRemoteAppOrgIdUser successfully removed {0} users the new count is {1}.", countOfDeletedUsers, countOfExistingUsers - countOfDeletedUsers); + } + [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void RemoveMSAUserThatExists() diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/packages.config b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/packages.config index e5c78e763cc5..1290d7a1161c 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/packages.config +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/packages.config @@ -13,7 +13,7 @@ - + diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/Model/CollectionAclLevel.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/Model/CollectionAclLevel.cs new file mode 100644 index 000000000000..c2adf12c0293 --- /dev/null +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/Model/CollectionAclLevel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LocalModels +{ + public enum CollectionAclLevel + { + Collection, + Application + } +} \ No newline at end of file diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/Model/Collections.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/Model/Collections.cs index c6ddadec6d0b..079f47057213 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/Model/Collections.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/Model/Collections.cs @@ -42,6 +42,7 @@ public Collection(Microsoft.WindowsAzure.Management.RemoteApp.Models.Collection TemplateImageName = col.TemplateImageName; TrialOnly = col.TrialOnly; VNetName = String.IsNullOrWhiteSpace(col.VNetName) || col.VNetName.StartsWith ("simplevnet-") ? "" : col.VNetName; + AclLevel = col.AclLevel; } } } diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/SetAzureRemoteAppCollection.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/SetAzureRemoteAppCollection.cs index 7a41248fae80..a581a4b01d28 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/SetAzureRemoteAppCollection.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Collection/SetAzureRemoteAppCollection.cs @@ -28,6 +28,7 @@ public class SetAzureRemoteAppCollection : RdsCmdlet private const string RdpPropertyOnly = "RdpPropertyOnly"; private const string DescriptionOnly = "DescriptionOnly"; private const string PlanOnly = "PlanOnly"; + private const string AclLevelOnly = "AclLevelOnly"; [Parameter(Mandatory = true, Position = 0, @@ -65,6 +66,13 @@ public class SetAzureRemoteAppCollection : RdsCmdlet [ValidateNotNull] public string CustomRdpProperty { get; set; } + [Parameter(Mandatory = true, + ValueFromPipelineByPropertyName = true, + ParameterSetName = AclLevelOnly, + HelpMessage = "Specifies at which level ACLs are set. Possible values: Collection, Application.")] + [ValidateNotNullOrEmpty] + public LocalModels.CollectionAclLevel AclLevel { get; set; } + public override void ExecuteCmdlet() { NetworkCredential creds = null; @@ -120,6 +128,42 @@ public override void ExecuteCmdlet() { details.CustomRdpProperty = CustomRdpProperty; } + else if (this.ParameterSetName == AclLevelOnly) + { + CollectionAclLevel newAclLevel = CollectionAclLevel.Unknown; + + switch(AclLevel) + { + case LocalModels.CollectionAclLevel.Application: + newAclLevel = CollectionAclLevel.Application; + break; + + case LocalModels.CollectionAclLevel.Collection: + newAclLevel = CollectionAclLevel.Collection; + break; + + default: + ErrorRecord er = RemoteAppCollectionErrorState.CreateErrorRecordFromString( + "Invalid value for AclLevel parameter.", + String.Empty, + Client.Collections, + ErrorCategory.InvalidArgument); + ThrowTerminatingError(er); + break; + } + + if(collection.AclLevel == newAclLevel) + { + ErrorRecord er = RemoteAppCollectionErrorState.CreateErrorRecordFromString( + String.Format("Collection is already in desired ACL level: {0}.", newAclLevel.ToString()), + String.Empty, + Client.Collections, + ErrorCategory.InvalidArgument); + ThrowTerminatingError(er); + } + + details.AclLevel = newAclLevel; + } else { ErrorRecord er = RemoteAppCollectionErrorState.CreateErrorRecordFromString( diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj index 3f5ff56acca2..724e222d65fd 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj @@ -120,8 +120,8 @@ ..\..\..\packages\Microsoft.WindowsAzure.Management.Network.7.0.4\lib\net40\Microsoft.WindowsAzure.Management.Network.dll - - ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.2\lib\net40\Microsoft.WindowsAzure.Management.RemoteApp.dll + + ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.5\lib\net40\Microsoft.WindowsAzure.Management.RemoteApp.dll ..\..\..\packages\Microsoft.WindowsAzure.Management.Storage.5.1.1\lib\net40\Microsoft.WindowsAzure.Management.Storage.dll @@ -178,6 +178,7 @@ + diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Microsoft.WindowsAzure.Commands.RemoteApp.dll-help.xml b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Microsoft.WindowsAzure.Commands.RemoteApp.dll-help.xml index e6d871e11012..a7c902517df8 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Microsoft.WindowsAzure.Commands.RemoteApp.dll-help.xml +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Microsoft.WindowsAzure.Commands.RemoteApp.dll-help.xml @@ -49,6 +49,13 @@ string[] + + Alias + + Published program alias (applicable only in per-app publishing mode) + + String + @@ -109,6 +116,19 @@ + + Alias + + Published program alias (applicable only in per-app publishing mode) + + String + + String + + + + + @@ -1912,6 +1932,13 @@ Get-AzureRemoteAppTemplateImage -ImageName ContosoApps string + + Alias + + Published program alias (applicable only in per-app publishing mode) + + String + @@ -1942,7 +1969,20 @@ Get-AzureRemoteAppTemplateImage -ImageName ContosoApps - + + Alias + + Published program alias (applicable only in per-app publishing mode) + + String + + String + + + + + + @@ -4400,6 +4440,13 @@ Remove-AzureRemoteAppTemplateImage -ImageName ContosoApps string[] + + Alias + + Published program alias (applicable only in per-app publishing mode) + + String + @@ -4460,6 +4507,19 @@ Remove-AzureRemoteAppTemplateImage -ImageName ContosoApps + + Alias + + Published program alias (applicable only in per-app publishing mode) + + String + + String + + + + + @@ -5295,6 +5355,23 @@ Send-AzureRemoteAppSessionMessage -CollectionName ContosoApps -UserUpn user@cont string + + Set-AzureRemoteAppCollection + + CollectionName + + Name of the Microsoft Azure RemoteApp collection. + + string + + + AclLevel + + Specifies at which level ACLs are set. Possible values: Collection, Application. + + CollectionAclLevel + + @@ -5363,6 +5440,18 @@ Send-AzureRemoteAppSessionMessage -CollectionName ContosoApps -UserUpn user@cont + + AclLevel + + Specifies at which level ACLs are set. Possible values: Collection, Application. + + CollectionAclLevel + + CollectionAclLevel + + + + diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/AddAzureRemoteAppUser.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/AddAzureRemoteAppUser.cs index 33e3c540a997..424a69ed3de3 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/AddAzureRemoteAppUser.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/AddAzureRemoteAppUser.cs @@ -22,7 +22,7 @@ public class AddAzureRemoteAppUser : SecurityPrincipals { public override void ExecuteCmdlet() { - AddUsers(CollectionName, UserUpn, Type); + AddUsers(CollectionName, UserUpn, Type, Alias); } } } diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/GetAzureRemoteAppUser.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/GetAzureRemoteAppUser.cs index a7cef1a5674e..7bf2577edff8 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/GetAzureRemoteAppUser.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/GetAzureRemoteAppUser.cs @@ -40,6 +40,11 @@ public class GetAzureRemoteAppUser : RdsCmdlet [ValidateNotNullOrEmpty()] public string UserUpn { get; set; } + [Parameter(Mandatory = false, + HelpMessage = "Published program alias (applicable only in per-app publishing mode)")] + [ValidateNotNullOrEmpty()] + public string Alias { get; set; } + private bool showAllUsers = false; public class ServicePrincipalComparer : IComparer @@ -137,7 +142,14 @@ public override void ExecuteCmdlet() } // You must pass in an empty string to this call. After that pass in the token returned by the previous call - response = CallClient(() => Client.Principals.List(CollectionName), Client.Principals); + if (String.IsNullOrEmpty(Alias)) + { + response = CallClient(() => Client.Principals.List(CollectionName), Client.Principals); + } + else + { + response = CallClient(() => Client.Principals.ListForApp(CollectionName, Alias), Client.Principals); + } if (response != null && response.SecurityPrincipalInfoList != null) { diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/RemoveAzureRemoteAppUser.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/RemoveAzureRemoteAppUser.cs index df2e58699b24..5f61889a6baa 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/RemoveAzureRemoteAppUser.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/RemoveAzureRemoteAppUser.cs @@ -22,7 +22,7 @@ public class RemoveAzureRemoteAppUser : SecurityPrincipals { public override void ExecuteCmdlet() { - RemoveUsers(CollectionName, UserUpn, Type); + RemoveUsers(CollectionName, UserUpn, Type, Alias); } } } diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/SecurityPrincipals.cs b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/SecurityPrincipals.cs index aa70e3ec1ceb..2e6b17806363 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/SecurityPrincipals.cs +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/SecurityPrincipals/SecurityPrincipals.cs @@ -43,13 +43,18 @@ public class SecurityPrincipals : RdsCmdlet [ValidatePattern(UserPrincipalValdatorString)] public string[] UserUpn { get; set; } + [Parameter(Mandatory = false, + HelpMessage = "Published program alias (applicable only in per-app publishing mode)")] + [ValidateNotNullOrEmpty()] + public string Alias { get; set; } + protected enum Operation { Add, Remove } - protected void AddUsers(string CollectionName, string[] users, PrincipalProviderType userIdType) + protected void AddUsers(string CollectionName, string[] users, PrincipalProviderType userIdType, string appAlias) { SecurityPrincipalOperationsResult response = null; SecurityPrincipalList spAdd = null; @@ -58,7 +63,14 @@ protected void AddUsers(string CollectionName, string[] users, PrincipalProvider { spAdd = BuildUserList(users, userIdType); - response = CallClient(() => Client.Principals.Add(CollectionName, spAdd), Client.Principals); + if (String.IsNullOrEmpty(appAlias)) + { + response = CallClient(() => Client.Principals.Add(CollectionName, spAdd), Client.Principals); + } + else + { + response = CallClient(() => Client.Principals.AddToApp(CollectionName, appAlias, spAdd), Client.Principals); + } } if (response != null) @@ -67,7 +79,7 @@ protected void AddUsers(string CollectionName, string[] users, PrincipalProvider } } - protected void RemoveUsers(string CollectionName, string[] users, PrincipalProviderType userIdType) + protected void RemoveUsers(string CollectionName, string[] users, PrincipalProviderType userIdType, string appAlias) { SecurityPrincipalOperationsResult response = null; SecurityPrincipalList spRemove = null; @@ -76,7 +88,14 @@ protected void RemoveUsers(string CollectionName, string[] users, PrincipalProvi { spRemove = BuildUserList(users, userIdType); - response = CallClient(() => Client.Principals.Delete(CollectionName, spRemove), Client.Principals); + if (String.IsNullOrEmpty(appAlias)) + { + response = CallClient(() => Client.Principals.Delete(CollectionName, spRemove), Client.Principals); + } + else + { + response = CallClient(() => Client.Principals.DeleteFromApp(CollectionName, appAlias, spRemove), Client.Principals); + } } if (response != null) diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config index 4f7527fedacd..11e202e8f3e1 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config @@ -18,7 +18,7 @@ - + From 357656c6b1a262c3e87edca21dafe202d1492e53 Mon Sep 17 00:00:00 2001 From: Vadim Ponomarev Date: Mon, 4 Jan 2016 17:47:10 -0800 Subject: [PATCH 2/2] Azure RemoteApp: updating version number --- .../Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj | 2 +- .../RemoteApp/Commands.RemoteApp.Test/packages.config | 2 +- .../RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj | 2 +- .../RemoteApp/Commands.RemoteApp/packages.config | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj index 908a3967d4d5..edf05c9b9fa4 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/Commands.RemoteApp.Test.csproj @@ -145,7 +145,7 @@ ..\..\..\packages\Microsoft.WindowsAzure.Management.4.1.1\lib\net40\Microsoft.WindowsAzure.Management.dll - ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.5\lib\net40\Microsoft.WindowsAzure.Management.RemoteApp.dll + ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.4\lib\net40\Microsoft.WindowsAzure.Management.RemoteApp.dll ..\..\..\packages\Moq.4.2.1402.2112\lib\net40\Moq.dll diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/packages.config b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/packages.config index efe15a19cd0e..b3759d36add5 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/packages.config +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp.Test/packages.config @@ -13,7 +13,7 @@ - + diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj index 4956d78e5316..d027dda5bb71 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj @@ -121,7 +121,7 @@ ..\..\..\packages\Microsoft.WindowsAzure.Management.Network.7.0.4\lib\net40\Microsoft.WindowsAzure.Management.Network.dll - ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.5\lib\net40\Microsoft.WindowsAzure.Management.RemoteApp.dll + ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.4\lib\net40\Microsoft.WindowsAzure.Management.RemoteApp.dll ..\..\..\packages\Microsoft.WindowsAzure.Management.Storage.5.1.1\lib\net40\Microsoft.WindowsAzure.Management.Storage.dll diff --git a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config index 2c2d767b1e6b..f56788846f06 100644 --- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config +++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config @@ -18,7 +18,7 @@ - +