Skip to content

Commit ada220f

Browse files
authored
Merge pull request #116 from UiPath/fix/folders
Better Folder support
2 parents e56d348 + ad59ee3 commit ada220f

File tree

11 files changed

+222
-24
lines changed

11 files changed

+222
-24
lines changed

.vsts-ci.yml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
queue:
2-
name: Hosted VS2017
3-
demands:
4-
- npm
5-
- msbuild
6-
- visualstudio
7-
- vstest
8-
1+
pool:
2+
name: Azure Pipelines
3+
vmImage: windows-2019
4+
95
variables:
106
Solution: "UiPath.Orchestrator.Powershell.sln"
117
BuildConfiguration: "Release"

Directory.Build.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Project>
2+
<PropertyGroup>
3+
<LangVersion>8.0</LangVersion>
4+
</PropertyGroup>
5+
</Project>

UiPath.PowerShell/Cmdlets/GetAuthToken.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
using Microsoft.Rest;
22
using System;
3-
using System.Collections.Generic;
43
using System.Linq;
54
using System.Management.Automation;
65
using System.Net.Http;
7-
using System.Security.Cryptography;
8-
using System.Text;
96
using System.Windows.Forms;
107
using UiPath.PowerShell.Models;
118
using UiPath.PowerShell.OAuth;
129
using UiPath.PowerShell.Util;
1310
using UiPath.Web.Client20181;
1411
using UiPath.Web.Client20181.Models;
1512

13+
1614
namespace UiPath.PowerShell.Cmdlets
1715
{
1816
/// <summary>
@@ -124,6 +122,14 @@ public class GetAuthToken: UiPathCmdlet
124122
[Parameter(Mandatory = false, ParameterSetName = CloudAPISet)]
125123
public string OrganizationUnit { get; set; }
126124

125+
[Parameter(Mandatory = false, ParameterSetName = UserPasswordSet)]
126+
[Parameter(Mandatory = false, ParameterSetName = WindowsCredentialsSet)]
127+
[Parameter(Mandatory = false, ParameterSetName = UnauthenticatedSet)]
128+
[Parameter(Mandatory = false, ParameterSetName = CloudInteractiveSet)]
129+
[Parameter(Mandatory = false, ParameterSetName = CloudCodeSet)]
130+
[Parameter(Mandatory = false, ParameterSetName = CloudAPISet)]
131+
public string FolderPath { get; set; }
132+
127133
[Parameter(Mandatory = false, ParameterSetName = UserPasswordSet)]
128134
[Parameter(Mandatory = false, ParameterSetName = WindowsCredentialsSet)]
129135
[Parameter(Mandatory = false, ParameterSetName = UnauthenticatedSet)]
@@ -200,11 +206,24 @@ protected override void ProcessRecord()
200206

201207
GetServerVersion(authToken);
202208

203-
if (!String.IsNullOrWhiteSpace(OrganizationUnit))
209+
if (!string.IsNullOrWhiteSpace(OrganizationUnit))
204210
{
211+
if (authToken.ApiVersion >= OrchestratorProtocolVersion.V19_10)
212+
{
213+
WriteWarning("The use of OrganizationUnit is deprecated and will be removed. Use FolderName instead.");
214+
}
205215
SetOrganizationUnit(authToken, OrganizationUnit);
206216
}
207217

218+
if (!string.IsNullOrWhiteSpace(FolderPath))
219+
{
220+
if (authToken.ApiVersion < OrchestratorProtocolVersion.V19_10)
221+
{
222+
WriteError("Use of FolderName requires Orchestrator version 19.10 or newer.");
223+
}
224+
SetCurrentFolder(authToken, FolderPath, Timeout);
225+
}
226+
208227
authToken.TenantName = authToken.TenantName ?? TenantName ?? "Default";
209228

210229
if (Session.IsPresent)
@@ -228,9 +247,11 @@ private void SetOrganizationUnit(AuthToken authToken, string organizationUnit)
228247
var unit = HandleHttpOperationException(() => api.OrganizationUnits.GetOrganizationUnits(filter: $"DisplayName eq '{organizationUnit}'").Value.First(ou => ou.DisplayName == organizationUnit));
229248
authToken.OrganizationUnit = unit.DisplayName;
230249
authToken.OrganizationUnitId = unit.Id.Value;
250+
authToken.CurrentFolder = default;
231251
}
232252
}
233253

254+
234255
private void GetServerVersion(AuthToken authToken)
235256
{
236257
authToken.ApiVersion = OrchestratorProtocolVersion.V18_1;

UiPath.PowerShell/Cmdlets/Nouns.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ internal static class Nouns
1414
internal const string FolderUser = UiPath + "FolderUser";
1515
internal const string FolderUserRoles = UiPath + "FolderUserRoles";
1616
internal const string FolderCurrentUser = UiPath + "CurrentUserFolders";
17+
internal const string FolderCurrent = UiPath + "CurrentFolder";
1718
internal const string Job = UiPath + "Job";
1819
internal const string Library = UiPath + "Library";
1920
internal const string LibraryVersion = UiPath + "LibraryVersion";
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using System.Management.Automation;
3+
using UiPath.PowerShell.Models;
4+
using UiPath.PowerShell.Util;
5+
6+
namespace UiPath.PowerShell.Cmdlets
7+
{
8+
/// <summary>
9+
/// <para type="synopsis">Changes the current Folder under which all other cmdlets are evaluated</para>
10+
/// <example>
11+
/// <code>Set-UiPathCurrentFolder Some/Folder/Path</code>
12+
/// </example>
13+
/// </summary>
14+
[Cmdlet(VerbsCommon.Set, Nouns.FolderCurrent)]
15+
public class SetCurrentFolder : AuthenticatedCmdlet
16+
{
17+
public const string FolderSet = "FolderSet";
18+
public const string FolderPathSet = "FolderPathSet";
19+
20+
[Parameter(Mandatory = true, ParameterSetName = FolderSet, Position = 1, ValueFromPipeline = true)]
21+
public Folder Folder { get; set; }
22+
23+
[Parameter(Mandatory = true, ParameterSetName = FolderPathSet, Position = 1)]
24+
public string FolderPath { get; set; }
25+
26+
protected override void ProcessRecord()
27+
{
28+
var token = InternalAuthToken;
29+
30+
SetCurrentFolder(token, Folder?.FullyQualifiedName ?? FolderPath, TimeSpan.FromSeconds(token.RequestTimeout ?? 100));
31+
32+
WriteObject(token);
33+
}
34+
}
35+
}

UiPath.PowerShell/Models/AuthToken.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public class AuthToken
2626

2727
public string OrganizationUnit { get; internal set; }
2828

29+
public Folder CurrentFolder { get; internal set; }
30+
2931
public string TenantName { get; internal set; }
3032

3133
public string AccountName { get; internal set; }

UiPath.PowerShell/Util/AuthenticatedCmdlet.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ internal static void RefreshAuthToken(AuthToken authToken)
309309
authToken.AccountName = accountLogicalName;
310310
}
311311

312+
internal static UiPathWebApi_19_10 MakeApi_19_10(AuthToken authToken, TimeSpan timeout) => MakeApi<UiPathWebApi_19_10>(
313+
authToken,
314+
(creds, uri) => new UiPathWebApi_19_10(creds) { BaseUri = uri },
315+
timeout);
316+
312317
internal static T MakeApi<T>(AuthToken authToken, Func<ServiceClientCredentials, Uri, T> ctor, TimeSpan timeout) where T:ServiceClient<T>, IUiPathWebApi
313318
{
314319
ServiceClientCredentials creds = null;

UiPath.PowerShell/Util/UiPathCmdlet.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
using Microsoft.Rest;
22
using Newtonsoft.Json.Linq;
33
using System;
4+
using System.Linq;
45
using System.Management.Automation;
6+
using System.Threading.Tasks;
7+
using UiPath.PowerShell.Models;
58

69
namespace UiPath.PowerShell.Util
710
{
@@ -75,6 +78,25 @@ protected override void EndProcessing()
7578
VerboseTracer.StopTracing();
7679
}
7780

81+
/// <summary>
82+
/// Handle the swagger generated idiocy
83+
/// </summary>
84+
/// <typeparam name="T"></typeparam>
85+
/// <param name="action"></param>
86+
/// <returns></returns>
87+
protected T HandleHttpResponseException<T>(Func<Task<HttpOperationResponse<T>>> action) => HandleHttpOperationException(() =>
88+
{
89+
var task = action();
90+
var response = task.Result;
91+
if (!response.Response.IsSuccessStatusCode)
92+
{
93+
var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", response.Response.StatusCode));
94+
ex.Request = new HttpRequestMessageWrapper(response.Request, response.Request?.Content?.AsString() ?? string.Empty);
95+
ex.Response = new HttpResponseMessageWrapper(response.Response, response.Response?.Content?.AsString() ?? string.Empty);
96+
throw ex;
97+
}
98+
return response.Body;
99+
});
78100
protected T HandleHttpOperationException<T>(Func<T> action)
79101
{
80102
try
@@ -156,5 +178,32 @@ internal static void ApplyEnumMember<TEnum>(string stringValue, Action<TEnum> ac
156178
action(enumValue);
157179
}
158180
}
181+
182+
internal void SetCurrentFolder(AuthToken authToken, string folderPath, TimeSpan timeout)
183+
{
184+
var oldFolderId = authToken.OrganizationUnitId;
185+
authToken.OrganizationUnitId = default;
186+
try
187+
{
188+
using (var api = AuthenticatedCmdlet.MakeApi_19_10(authToken, timeout))
189+
{
190+
var folders = HandleHttpResponseException(() => api.Folders.GetFoldersWithHttpMessagesAsync(filter: $"FullyQualifiedName eq '{Uri.EscapeDataString(folderPath)}'")).Value;
191+
if (folders.Count != 1)
192+
{
193+
throw new Exception($"The folder path '{folderPath}' does not select exactly one Folder");
194+
}
195+
196+
var folder = folders.Single();
197+
authToken.CurrentFolder = Folder.FromDto(folder);
198+
authToken.OrganizationUnit = default;
199+
authToken.OrganizationUnitId = folder.Id;
200+
}
201+
}
202+
catch
203+
{
204+
authToken.OrganizationUnitId = oldFolderId;
205+
throw;
206+
}
207+
}
159208
}
160209
}

docs/Get-UiPathAuthToken.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,29 @@ SYNOPSIS
99
1010
SYNTAX
1111
Get-UiPathAuthToken [-AccountName <string>] [-AccountUrl <string>] [-ApplicationId <string>] [-AuthorizationUrl
12-
<string>] [-CloudDeployment <string>] [-OrganizationUnit <string>] [-Private <SwitchParameter>] [-RequestTimeout
13-
<int>] [-Session <SwitchParameter>] [-TenantName <string>] [<CommonParameters>]
12+
<string>] [-CloudDeployment <string>] [-FolderPath <string>] [-OrganizationUnit <string>] [-Private
13+
<SwitchParameter>] [-RequestTimeout <int>] [-Session <SwitchParameter>] [-TenantName <string>] [<CommonParameters>]
1414
1515
Get-UiPathAuthToken -AuthorizationCode <string> -AuthorizationVerifier <string> [-AccountName <string>]
1616
[-AccountUrl <string>] [-ApplicationId <string>] [-AuthorizationUrl <string>] [-CloudDeployment <string>]
17-
[-OrganizationUnit <string>] [-RequestTimeout <int>] [-Session <SwitchParameter>] [-TenantName <string>]
18-
[<CommonParameters>]
17+
[-FolderPath <string>] [-OrganizationUnit <string>] [-RequestTimeout <int>] [-Session <SwitchParameter>]
18+
[-TenantName <string>] [<CommonParameters>]
1919
2020
Get-UiPathAuthToken -ClientId <string> -UserKey <string> [-AccountName <string>] [-CloudDeployment <string>]
21-
[-OrganizationUnit <string>] [-RequestTimeout <int>] [-Session <SwitchParameter>] [-TenantName <string>]
22-
[<CommonParameters>]
21+
[-FolderPath <string>] [-OrganizationUnit <string>] [-RequestTimeout <int>] [-Session <SwitchParameter>]
22+
[-TenantName <string>] [<CommonParameters>]
2323
2424
Get-UiPathAuthToken -CurrentSession <SwitchParameter> [-RequestTimeout <int>] [<CommonParameters>]
2525
26-
Get-UiPathAuthToken [-URL] <string> -Password <string> -Username <string> [-OrganizationUnit <string>]
27-
[-RequestTimeout <int>] [-Session <SwitchParameter>] [-TenantName <string>] [<CommonParameters>]
26+
Get-UiPathAuthToken [-URL] <string> -Password <string> -Username <string> [-FolderPath <string>]
27+
[-OrganizationUnit <string>] [-RequestTimeout <int>] [-Session <SwitchParameter>] [-TenantName <string>]
28+
[<CommonParameters>]
2829
29-
Get-UiPathAuthToken [-URL] <string> -WindowsCredentials <SwitchParameter> [-OrganizationUnit <string>]
30-
[-RequestTimeout <int>] [-Session <SwitchParameter>] [<CommonParameters>]
30+
Get-UiPathAuthToken [-URL] <string> -WindowsCredentials <SwitchParameter> [-FolderPath <string>]
31+
[-OrganizationUnit <string>] [-RequestTimeout <int>] [-Session <SwitchParameter>] [<CommonParameters>]
3132
32-
Get-UiPathAuthToken [-URL] <string> -Unauthenticated <SwitchParameter> [-OrganizationUnit <string>]
33-
[-RequestTimeout <int>] [-Session <SwitchParameter>] [-TenantName <string>] [<CommonParameters>]
33+
Get-UiPathAuthToken [-URL] <string> -Unauthenticated <SwitchParameter> [-FolderPath <string>] [-OrganizationUnit
34+
<string>] [-RequestTimeout <int>] [-Session <SwitchParameter>] [-TenantName <string>] [<CommonParameters>]
3435
3536
3637
DESCRIPTION
@@ -182,6 +183,14 @@ PARAMETERS
182183
Accept pipeline input? false
183184
Accept wildcard characters? false
184185
186+
-FolderPath <string>
187+
188+
Required? false
189+
Position? named
190+
Default value
191+
Accept pipeline input? false
192+
Accept wildcard characters? false
193+
185194
-Session <SwitchParameter>
186195
187196
Required? false

docs/Home.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
- [Remove-UiPathWebhook](Remove-UiPathWebhook.md)
8484
- [Revoke-UiPathRolePermission](Revoke-UiPathRolePermission.md)
8585
- [Set-UiPathAuthToken](Set-UiPathAuthToken.md)
86+
- [Set-UiPathCurrentFolder](Set-UiPathCurrentFolder.md)
8687
- [Start-UiPathJob](Start-UiPathJob.md)
8788
- [Start-UiPathMaintenance](Start-UiPathMaintenance.md)
8889
- [Stop-UiPathJob](Stop-UiPathJob.md)

0 commit comments

Comments
 (0)