Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 4fbba3b

Browse files
committed
Refactor of Authentication
1 parent 3dd34ee commit 4fbba3b

14 files changed

+2069
-39
lines changed

example/service.parameters.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
"contentVersion": "1.0.0.0",
55
"parameters": {
66
"publisherEmail": {
7-
"value": "admin@contoso.com"
7+
"value": "odaibert@microsoft.com"
88
},
99
"publisherName": {
10-
"value": "Contoso"
10+
"value": "odaibert"
1111
},
1212
"ApimServiceName": {
13-
"value": "contosoapim-dev"
13+
"value": "odaibert-deploy"
1414
}
1515
}
1616
}

src/apimtemplate.test/CmdLine/ExtractTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ public class ExtractTests
1010
[Fact]
1111
public void ShouldFailWithUnknownCommand()
1212
{
13+
//arrange - do all your instatiation and configuration
1314

15+
//act - execute
16+
17+
//assert
1418
var createCommand = new ExtractCommand();
1519

1620
var ex = Assert.ThrowsAny<CommandParsingException>(() => createCommand.Execute("test"));

src/apimtemplate/Commands/Extract.cs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using System;
22
using McMaster.Extensions.CommandLineUtils;
33
using Colors.Net;
4-
using System.Net.Http;
5-
using System.Net.Http.Headers;
4+
using Newtonsoft.Json.Linq;
5+
using System.Linq;
6+
using Newtonsoft.Json;
67

78
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates
89
{
@@ -13,45 +14,45 @@ public ExtractCommand()
1314
this.Name = Constants.ExtractName;
1415
this.Description = Constants.ExtractDescription;
1516

16-
var apimname = this.Option("--name <apimname>", "API Management name", CommandOptionType.SingleValue).IsRequired();
17-
18-
var auth = new Authentication();
19-
20-
var aztoken = auth.GetAccessToken().Result;
17+
var apiManagementName = this.Option("--name <apimname>", "API Management name", CommandOptionType.SingleValue).IsRequired();
2118

2219
this.HelpOption();
23-
24-
this.OnExecute(async () =>
20+
21+
this.OnExecute(() =>
2522
{
26-
if (apimname.HasValue())
27-
{
28-
Console.WriteLine($"Create command executed with name {apimname.Value()}");
29-
30-
string requestUrl = "https://management.azure.com/subscriptions/cabe3525-a754-4bf7-9af4-1a9746604527/resourceGroups/apim-extractor/providers/Microsoft.ApiManagement/service/apim-extractor/apis/odaibert-logicapp/products?api-version=2018-06-01-preview";
31-
32-
using (HttpClient httpClient = new HttpClient())
33-
{
34-
var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
23+
if (apiManagementName.HasValue()) throw new Exception("Missing parameter(s)."); //Validade if is better exception or not
3524

36-
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", aztoken);
25+
string resourceGroup = "APIM-Extractor"; //change to get from commandline parameter
26+
string apimname;
27+
string apis;
28+
int count;
3729

38-
HttpResponseMessage response = await httpClient.SendAsync(request);
30+
Api api = new Api();
31+
JObject oApis;
3932

40-
response.EnsureSuccessStatusCode();
33+
apimname = apiManagementName.Values[0].ToString();
34+
apis = api.GetAPIs(apimname, resourceGroup).Result;
35+
oApis = JObject.Parse(apis);
36+
count = oApis["value"].Count<object>();
4137

42-
string responseBody = await response.Content.ReadAsStringAsync();
38+
Console.WriteLine("{0} API's found!", count);
4339

44-
ColoredConsole.Write(responseBody.ToString());
45-
Console.ReadKey();
46-
}
47-
}
48-
else
40+
for (int i = 0; i < count; i++)
4941
{
50-
ColoredConsole.Error.WriteLine("API Management name passed in");
42+
Console.WriteLine(oApis);
43+
string apiname = (string)oApis["value"][i]["name"];
44+
ColoredConsole.WriteLine(apiname);
45+
ColoredConsole.WriteLine(api.GetAPIOperations(apimname, resourceGroup, apiname).Result);
5146
}
47+
Console.ReadKey();
48+
5249
return 0;
5350
});
54-
51+
}
52+
private static string FormatJSON(string json)
53+
{
54+
dynamic parsedJson = JsonConvert.DeserializeObject(json);
55+
return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
5556
}
5657
}
5758
}

src/apimtemplate/Common/Api.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Net.Http;
4+
using System.Net.Http.Headers;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates
9+
{
10+
class Api
11+
{
12+
static string baseUrl = "https://management.azure.com";
13+
internal Authentication auth = new Authentication();
14+
public async Task<string> GetAPIOperations(string ApiManagementName, string ResourceGroupName, string ApiName)
15+
{
16+
(string azToken, string azSubId) = await auth.GetAccessToken();
17+
18+
string requestUrl = string.Format("{0}/subscriptions/{1}/resourceGroups/{2}/providers/Microsoft.ApiManagement/service/{3}/apis/{4}/operations?api-version={5}",
19+
baseUrl, azSubId, ResourceGroupName, ApiManagementName, ApiName, Constants.APIVersion);
20+
21+
return await CallApiManagement(azToken, requestUrl);
22+
23+
}
24+
public async Task<string> GetAPIs(string ApiManagementName, string ResourceGroupName)
25+
{
26+
(string azToken, string azSubId) = await auth.GetAccessToken();
27+
28+
string requestUrl = string.Format("{0}/subscriptions/{1}/resourceGroups/{2}/providers/Microsoft.ApiManagement/service/{3}/apis?api-version={4}",
29+
baseUrl, azSubId, ResourceGroupName, ApiManagementName, Constants.APIVersion);
30+
31+
return await CallApiManagement(azToken, requestUrl);
32+
33+
}
34+
private static async Task<string> CallApiManagement(string azToken, string requestUrl)
35+
{
36+
using (HttpClient httpClient = new HttpClient())
37+
{
38+
var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
39+
40+
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", azToken);
41+
42+
HttpResponseMessage response = await httpClient.SendAsync(request);
43+
44+
response.EnsureSuccessStatusCode();
45+
46+
string responseBody = await response.Content.ReadAsStringAsync();
47+
48+
return responseBody;
49+
}
50+
}
51+
}
52+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Newtonsoft.Json.Linq;
4+
5+
namespace APIManagementTemplate
6+
{
7+
public class ApiVersionSetIdComparer : IEqualityComparer<JToken>
8+
{
9+
private const string Properties = "properties";
10+
private const string ApiVersionSetId = "apiVersionSetId";
11+
12+
public bool Equals(JToken x, JToken y)
13+
{
14+
if (x == null && y == null)
15+
return true;
16+
if (x == null || y == null)
17+
return false;
18+
if (x[Properties] == null || y[Properties] == null)
19+
return false;
20+
return x[Properties].Value<string>(ApiVersionSetId)
21+
.Equals(y[Properties].Value<string>(ApiVersionSetId));
22+
}
23+
24+
public int GetHashCode(JToken obj)
25+
{
26+
if (obj[Properties] == null)
27+
return obj.GetHashCode();
28+
return (obj[Properties].Value<string>(ApiVersionSetId) ?? String.Empty).GetHashCode();
29+
}
30+
}
31+
}

src/apimtemplate/Common/Authentication.cs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,24 @@ namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates
99
{
1010
public class Authentication
1111
{
12-
public async Task<string> GetAccessToken()
12+
public async Task<(string azToken, string azSubscriptionId)> GetAccessToken()
1313
{
14-
(bool cliSucceeded, string cliToken) = await TryGetAzCliToken();
14+
(bool cliTokenSucceeded, string cliToken) = await TryGetAzCliToken();
15+
(bool cliSubscriptionIdSucceeded, string cliSubscriptionId) = await TryGetAzSubscriptionId();
1516

16-
if (cliSucceeded) return cliToken;
17+
if (cliTokenSucceeded || cliSubscriptionIdSucceeded)
18+
{
19+
return (cliToken, cliSubscriptionId);
20+
}
1721

1822
throw new Exception("Unable to connect to Azure. Make sure you have the `az` CLI or Azure PowerShell installed and logged in and try again");
1923
}
2024

2125
private async Task<(bool succeeded, string token)> TryGetAzCliToken()
2226
{
2327
var az = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
24-
? new Executable("cmd", "/c az " + Constants.azParameters)
25-
: new Executable("az", Constants.azParameters);
28+
? new Executable("cmd", "/c az " + Constants.azAccessToken)
29+
: new Executable("az", Constants.azAccessToken);
2630

2731
var stdout = new StringBuilder();
2832
var stderr = new StringBuilder();
@@ -36,7 +40,23 @@ public async Task<string> GetAccessToken()
3640
return (false, stdout.ToString().Trim(' ', '\n', '\r', '"'));
3741
}
3842
}
43+
private async Task<(bool succeeded, string token)> TryGetAzSubscriptionId()
44+
{
45+
var az = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
46+
? new Executable("cmd", "/c az " + Constants.azSubscriptionId)
47+
: new Executable("az", Constants.azSubscriptionId);
3948

40-
}
49+
var stdout = new StringBuilder();
50+
var stderr = new StringBuilder();
51+
var completed = az.RunAsync(o => stdout.AppendLine(o), e => stderr.AppendLine(e));
4152

53+
if (await completed == 0)
54+
return (true, stdout.ToString().Trim(' ', '\n', '\r', '"'));
55+
else
56+
{
57+
ColoredConsole.WriteLine(($"Unable to fetch subscription id from az cli. Error: {stderr.ToString().Trim(' ', '\n', '\r')}"));
58+
return (false, stdout.ToString().Trim(' ', '\n', '\r', '"'));
59+
}
60+
}
61+
}
4262
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace APIManagementTemplate
8+
{
9+
public class AzureResourceId
10+
{
11+
12+
public string ResourceGroupName
13+
{
14+
get
15+
{
16+
if (this.splittedId.Length > 4)
17+
{
18+
return this.splittedId[4];
19+
}
20+
return "";
21+
}
22+
set
23+
{
24+
if (this.splittedId.Length > 4)
25+
{
26+
this.splittedId[4] = value;
27+
}
28+
}
29+
}
30+
public string SubscriptionId
31+
{
32+
get
33+
{
34+
if (this.splittedId.Length > 2)
35+
{
36+
return this.splittedId[2];
37+
}
38+
return "";
39+
}
40+
set
41+
{
42+
if (this.splittedId.Length > 2)
43+
{
44+
this.splittedId[2] = value;
45+
}
46+
}
47+
}
48+
public string ResourceName
49+
{
50+
get
51+
{
52+
return this.splittedId.Last();
53+
}
54+
set
55+
{
56+
this.splittedId[this.splittedId.Length - 1] = value;
57+
}
58+
}
59+
60+
public string ValueAfter(String type)
61+
{
62+
var rest = this.splittedId.SkipWhile(s => s != type).Skip(1);
63+
return rest.FirstOrDefault();
64+
}
65+
66+
public void ReplaceValueAfter(String type, string value)
67+
{
68+
var position = this.splittedId.TakeWhile(s => s != type).Count() + 1;
69+
if (position < this.splittedId.Length)
70+
this.splittedId[position] = value;
71+
}
72+
73+
private string[] splittedId;
74+
public AzureResourceId(string resourceid)
75+
{
76+
string replaced = "/" + resourceid.Substring(resourceid.IndexOf("subscriptions/"));
77+
this.splittedId = replaced.Split('/');
78+
}
79+
80+
public override string ToString()
81+
{
82+
return splittedId.Aggregate((a, n) => { return a + '/' + n; }).ToString();
83+
}
84+
}
85+
}

src/apimtemplate/Common/Constants.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ internal static class Constants
1111
public const string CreateDescription = "Create an API Management instance from files";
1212
public const string ExtractName = "extract";
1313
public const string ExtractDescription = "Extract an existing API Management instance";
14+
public const string APIVersion = "2018-06-01-preview";
1415

15-
public const string azParameters = "account get-access-token --query \"accessToken\" --output json";
16+
public const string azAccessToken = "account get-access-token --query \"accessToken\" --output json";
17+
public const string azSubscriptionId = "account get-access-token --query \"subscription\" --output json";
18+
internal static string deploymentSchema;
19+
internal static string deploymenParameterSchema;
1620
}
1721
}

0 commit comments

Comments
 (0)