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 aeafa929150f..edf05c9b9fa4 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.3\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/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 041e125f80df..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/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 f6b82d5fec56..d027dda5bb71 100644
--- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj
+++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/Commands.RemoteApp.csproj
@@ -121,8 +121,7 @@
..\..\..\packages\Microsoft.WindowsAzure.Management.Network.7.0.4\lib\net40\Microsoft.WindowsAzure.Management.Network.dll
- False
- ..\..\..\packages\Microsoft.WindowsAzure.Management.RemoteApp.2.0.3\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
@@ -179,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 2c8c6a0eda95..129f8b71e29e 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 137e11d451f9..f56788846f06 100644
--- a/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config
+++ b/src/ServiceManagement/RemoteApp/Commands.RemoteApp/packages.config
@@ -18,7 +18,7 @@
-
+