-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathApi.cs
88 lines (75 loc) · 3.3 KB
/
Api.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Functions.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Functions
{
public static class Api
{
const string AUTH_HEADER = "Authorization";
public static HttpClient httpClient = new HttpClient();
[FunctionName("Search")]
public static async Task<IActionResult> Search(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "{organization}/{project}/{feedId}/search")] HttpRequest req,
string organization,
string project,
string feedId,
ILogger log)
{
string debugAuth = null;
// Authorization header is expected in the following format: 'Basic base64Encode(<user>:<PAT>)'
// The header is automatically set by the npm command line if the .npmrc file(s) are configured
// - <user> can be any string
// - <PAT> required permissions: Packaging Read & write
if(!req.Headers.ContainsKey(AUTH_HEADER) && string.IsNullOrEmpty(debugAuth))
{
return new UnauthorizedResult();
}
string packageNameQuery = req.Query["text"];
string top = req.Query["size"];
string skip = req.Query["from"];
// Documented at: https://docs.microsoft.com/en-us/rest/api/azure/devops/artifacts/artifact-details/get-packages?view=azure-devops-rest-7.1
var packageSearchUrl = $"https://feeds.dev.azure.com/{organization}/{project}/_apis/packaging/Feeds/{feedId}/packages?protocolType=npm&packageNameQuery={packageNameQuery ?? string.Empty}&includeUrls=true&includeAllVersions=false&getTopPackageVersions=false&includeDescription=true&$top={top ?? "20"}&$skip={skip ?? "0"}&api-version=7.1-preview.1";
var packageRequest = new HttpRequestMessage(HttpMethod.Get, packageSearchUrl);
string authHeader = req.Headers[AUTH_HEADER];
authHeader = authHeader ?? debugAuth;
packageRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", authHeader.Replace("Basic ", string.Empty, true, CultureInfo.InvariantCulture));
var response = await httpClient.SendAsync(packageRequest);
var rawResult = await response.Content.ReadAsAsync<dynamic>();
AzureArtifactsPackageResult[] result = JsonConvert.DeserializeObject<AzureArtifactsPackageResult[]>(rawResult.value.ToString());
var npmSearchResult = new PackageResult
{
Objects = new List<PackageResult.Object>(result.Length),
Total = result.Length,
Time = DateTime.UtcNow.ToString("r")
};
foreach (var package in result)
{
npmSearchResult.Objects.AddRange(
package.Versions.Where(v => v.IsLatest).Select(v => new PackageResult.Object
{
Package = new PackageResult.Package
{
Name = package.Name,
Date = DateTime.Parse(v.PublishDate),
Description = v.PackageDescription,
Version = v.Version
}
}
)
);
}
return new OkObjectResult(npmSearchResult);
}
}
}