Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Commit 7220671

Browse files
authored
Merge pull request #270 from microsoftgraph/feat/add_environment_login
Add environment login.
2 parents a2848e3 + 60780e7 commit 7220671

File tree

12,397 files changed

+477838
-486768
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

12,397 files changed

+477838
-486768
lines changed

.azure-pipelines/config/PoliCheckExclusions.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
<!--<Exclusion Type="FileType">.ABC|.XYZ</Exclusion>-->
99
<!--The specified file names will be skipped during the scan regardless which folder they are in -->
1010
<!--<Exclusion Type="FileName">ABC.TXT|XYZ.CS</Exclusion>-->
11-
<Exclusion Type="FileName">COUNTRYNAMEDLOCATION.CS|LOCALEINFO.CS|ORGANIZATION.CS|PARENTALCONTROLSETTINGS.CS|PARTICIPANTINFO.CS|USER.CS|FUNCTIONSREQUESTBUILDER.CS</Exclusion>
12-
</PoliCheckExclusions>
11+
<Exclusion Type="FolderPathFull">SRC\GENERATED</Exclusion>
12+
</PoliCheckExclusions>

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
- Add Environment login. Client secret login and certificate file login are now possible with this new strategy.
12+
13+
### Changed
14+
- Update login command help text.
15+
- Fix a bug where the CLI didn't send the Content-Type header when sending requests with bodies.
16+
1017
## [0.2.0-preview.1] - 2023-02-27
1118

1219
### Added

src/Program.cs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,7 @@ class Program
4141
{
4242
static async Task<int> Main(string[] args)
4343
{
44-
var customCommands = new List<Command>();
45-
customCommands.Add(new LoginCommand().Build());
46-
customCommands.Add(new LogoutCommand().Build());
47-
48-
49-
var builder = BuildCommandLine(customCommands)
44+
var builder = BuildCommandLine()
5045
.UseDefaults()
5146
.UseHost(a =>
5247
{
@@ -75,7 +70,7 @@ static async Task<int> Main(string[] args)
7570
{
7671
var host = ic.GetHost();
7772

78-
ic.BindingContext.AddService(_ => host.Services.GetRequiredService<IAuthenticationCacheUtility>());
73+
ic.BindingContext.AddService(_ => host.Services.GetRequiredService<IAuthenticationCacheManager>());
7974
ic.BindingContext.AddService(_ => host.Services.GetRequiredService<AuthenticationServiceFactory>());
8075
// Needed by LogoutCommand
8176
ic.BindingContext.AddService(_ => host.Services.GetRequiredService<LogoutService>());
@@ -115,7 +110,7 @@ static async Task<int> Main(string[] args)
115110
return await parser.InvokeAsync(args);
116111
}
117112

118-
static CommandLineBuilder BuildCommandLine(IEnumerable<Command> commands)
113+
static CommandLineBuilder BuildCommandLine()
119114
{
120115
var rootCommand = new GraphClient().BuildRootCommand();
121116
rootCommand.Description = "Microsoft Graph CLI";
@@ -125,12 +120,11 @@ static CommandLineBuilder BuildCommandLine(IEnumerable<Command> commands)
125120
// --debug for configs.
126121
rootCommand.TreatUnmatchedTokensAsErrors = false;
127122

128-
foreach (var command in commands)
129-
{
130-
rootCommand.AddCommand(command);
131-
}
123+
var builder = new CommandLineBuilder(rootCommand);
124+
rootCommand.AddCommand(new LoginCommand(builder));
125+
rootCommand.AddCommand(new LogoutCommand());
132126

133-
return new CommandLineBuilder(rootCommand);
127+
return builder;
134128
}
135129

136130
static IHostBuilder CreateHostBuilder(string[] args) =>
@@ -188,13 +182,13 @@ static IHostBuilder CreateHostBuilder(string[] args) =>
188182
return new HttpClientRequestAdapter(authProvider, httpClient: client);
189183
});
190184
services.AddSingleton<IPathUtility, PathUtility>();
191-
services.AddSingleton<IAuthenticationCacheUtility, AuthenticationCacheUtility>();
185+
services.AddSingleton<IAuthenticationCacheManager, AuthenticationCacheManager>();
192186
services.AddSingleton<LogoutService>();
193187
services.AddSingleton<AuthenticationServiceFactory>(p =>
194188
{
195189
var authSettings = p.GetRequiredService<IOptions<AuthenticationOptions>>()?.Value;
196190
var pathUtil = p.GetRequiredService<IPathUtility>();
197-
var cacheUtil = p.GetRequiredService<IAuthenticationCacheUtility>();
191+
var cacheUtil = p.GetRequiredService<IAuthenticationCacheManager>();
198192
return new AuthenticationServiceFactory(pathUtil, cacheUtil, authSettings);
199193
});
200194
}).ConfigureLogging((ctx, logBuilder) =>
@@ -214,7 +208,7 @@ static void ConfigureAppConfiguration(IConfigurationBuilder builder, string[] ar
214208
builder.Sources.Clear();
215209
builder.AddJsonFile(Path.Combine(System.AppContext.BaseDirectory, "app-settings.json"), optional: true);
216210
var pathUtil = new PathUtility();
217-
var authCache = new AuthenticationCacheUtility(pathUtil);
211+
var authCache = new AuthenticationCacheManager(pathUtil);
218212
var dataDir = pathUtil.GetApplicationDataDirectory();
219213
var userConfigPath = Path.Combine(dataDir, "settings.json");
220214
builder.AddJsonFile(userConfigPath, optional: true);

src/generated/Admin/AdminRequestBuilder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ public Command BuildPatchCommand() {
119119
if (model is null) return; // Cannot create a POST request from a null model.
120120
var requestInfo = ToPatchRequestInformation(model, q => {
121121
});
122+
requestInfo.SetContentFromParsable(reqAdapter, "application/json", model);
122123
var errorMapping = new Dictionary<string, ParsableFactory<IParsable>> {
123124
{"4XX", ODataError.CreateFromDiscriminatorValue},
124125
{"5XX", ODataError.CreateFromDiscriminatorValue},

src/generated/Admin/ServiceAnnouncement/HealthOverviews/HealthOverviewsRequestBuilder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public Command BuildCreateCommand() {
8686
if (model is null) return; // Cannot create a POST request from a null model.
8787
var requestInfo = ToPostRequestInformation(model, q => {
8888
});
89+
requestInfo.SetContentFromParsable(reqAdapter, "application/json", model);
8990
var errorMapping = new Dictionary<string, ParsableFactory<IParsable>> {
9091
{"4XX", ODataError.CreateFromDiscriminatorValue},
9192
{"5XX", ODataError.CreateFromDiscriminatorValue},

src/generated/Admin/ServiceAnnouncement/HealthOverviews/Item/Issues/Count/CountRequestBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public Command BuildGetCommand() {
2929
var command = new Command("get");
3030
command.Description = "Get the number of the resource";
3131
// Create options for all the parameters
32-
var serviceHealthIdOption = new Option<string>("--service-health-id", description: "key: id of serviceHealth") {
32+
var serviceHealthIdOption = new Option<string>("--service-health-id", description: "The unique identifier of serviceHealth") {
3333
};
3434
serviceHealthIdOption.IsRequired = true;
3535
command.AddOption(serviceHealthIdOption);

src/generated/Admin/ServiceAnnouncement/HealthOverviews/Item/Issues/IssuesRequestBuilder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public Command BuildCommand() {
3333
var builder = new ServiceHealthIssueItemRequestBuilder(PathParameters);
3434
command.AddCommand(builder.BuildDeleteCommand());
3535
command.AddCommand(builder.BuildGetCommand());
36-
command.AddCommand(builder.BuildMicrosoftGraphIncidentReportCommand());
36+
command.AddCommand(builder.BuildIncidentReportCommand());
3737
command.AddCommand(builder.BuildPatchCommand());
3838
return command;
3939
}
@@ -54,7 +54,7 @@ public Command BuildCreateCommand() {
5454
var command = new Command("create");
5555
command.Description = "Create new navigation property to issues for admin";
5656
// Create options for all the parameters
57-
var serviceHealthIdOption = new Option<string>("--service-health-id", description: "key: id of serviceHealth") {
57+
var serviceHealthIdOption = new Option<string>("--service-health-id", description: "The unique identifier of serviceHealth") {
5858
};
5959
serviceHealthIdOption.IsRequired = true;
6060
command.AddOption(serviceHealthIdOption);
@@ -92,6 +92,7 @@ public Command BuildCreateCommand() {
9292
var requestInfo = ToPostRequestInformation(model, q => {
9393
});
9494
if (serviceHealthId is not null) requestInfo.PathParameters.Add("serviceHealth%2Did", serviceHealthId);
95+
requestInfo.SetContentFromParsable(reqAdapter, "application/json", model);
9596
var errorMapping = new Dictionary<string, ParsableFactory<IParsable>> {
9697
{"4XX", ODataError.CreateFromDiscriminatorValue},
9798
{"5XX", ODataError.CreateFromDiscriminatorValue},
@@ -111,7 +112,7 @@ public Command BuildListCommand() {
111112
var command = new Command("list");
112113
command.Description = "A collection of issues that happened on the service, with detailed information for each issue.";
113114
// Create options for all the parameters
114-
var serviceHealthIdOption = new Option<string>("--service-health-id", description: "key: id of serviceHealth") {
115+
var serviceHealthIdOption = new Option<string>("--service-health-id", description: "The unique identifier of serviceHealth") {
115116
};
116117
serviceHealthIdOption.IsRequired = true;
117118
command.AddOption(serviceHealthIdOption);
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
using ApiSdk.Models.ODataErrors;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.Hosting;
4+
using Microsoft.Kiota.Abstractions;
5+
using Microsoft.Kiota.Abstractions.Serialization;
6+
using Microsoft.Kiota.Cli.Commons.Extensions;
7+
using Microsoft.Kiota.Cli.Commons.IO;
8+
using System;
9+
using System.Collections.Generic;
10+
using System.CommandLine;
11+
using System.IO;
12+
using System.Linq;
13+
using System.Text;
14+
using System.Threading;
15+
using System.Threading.Tasks;
16+
namespace ApiSdk.Admin.ServiceAnnouncement.HealthOverviews.Item.Issues.Item.IncidentReport {
17+
/// <summary>
18+
/// Provides operations to call the incidentReport method.
19+
/// </summary>
20+
public class IncidentReportRequestBuilder {
21+
/// <summary>Path parameters for the request</summary>
22+
private Dictionary<string, object> PathParameters { get; set; }
23+
/// <summary>Url template to use to build the URL for the current request builder</summary>
24+
private string UrlTemplate { get; set; }
25+
/// <summary>
26+
/// Invoke function incidentReport
27+
/// </summary>
28+
public Command BuildGetCommand() {
29+
var command = new Command("get");
30+
command.Description = "Invoke function incidentReport";
31+
// Create options for all the parameters
32+
var serviceHealthIdOption = new Option<string>("--service-health-id", description: "The unique identifier of serviceHealth") {
33+
};
34+
serviceHealthIdOption.IsRequired = true;
35+
command.AddOption(serviceHealthIdOption);
36+
var serviceHealthIssueIdOption = new Option<string>("--service-health-issue-id", description: "The unique identifier of serviceHealthIssue") {
37+
};
38+
serviceHealthIssueIdOption.IsRequired = true;
39+
command.AddOption(serviceHealthIssueIdOption);
40+
var fileOption = new Option<FileInfo>("--file");
41+
command.AddOption(fileOption);
42+
command.SetHandler(async (invocationContext) => {
43+
var serviceHealthId = invocationContext.ParseResult.GetValueForOption(serviceHealthIdOption);
44+
var serviceHealthIssueId = invocationContext.ParseResult.GetValueForOption(serviceHealthIssueIdOption);
45+
var file = invocationContext.ParseResult.GetValueForOption(fileOption);
46+
var cancellationToken = invocationContext.GetCancellationToken();
47+
var reqAdapter = invocationContext.GetRequestAdapter();
48+
var requestInfo = ToGetRequestInformation(q => {
49+
});
50+
if (serviceHealthId is not null) requestInfo.PathParameters.Add("serviceHealth%2Did", serviceHealthId);
51+
if (serviceHealthIssueId is not null) requestInfo.PathParameters.Add("serviceHealthIssue%2Did", serviceHealthIssueId);
52+
var errorMapping = new Dictionary<string, ParsableFactory<IParsable>> {
53+
{"4XX", ODataError.CreateFromDiscriminatorValue},
54+
{"5XX", ODataError.CreateFromDiscriminatorValue},
55+
};
56+
var response = await reqAdapter.SendPrimitiveAsync<Stream>(requestInfo, errorMapping: errorMapping, cancellationToken: cancellationToken) ?? Stream.Null;
57+
if (file == null) {
58+
using var reader = new StreamReader(response);
59+
var strContent = reader.ReadToEnd();
60+
Console.Write(strContent);
61+
}
62+
else {
63+
using var writeStream = file.OpenWrite();
64+
await response.CopyToAsync(writeStream);
65+
Console.WriteLine($"Content written to {file.FullName}.");
66+
}
67+
});
68+
return command;
69+
}
70+
/// <summary>
71+
/// Instantiates a new IncidentReportRequestBuilder and sets the default values.
72+
/// </summary>
73+
/// <param name="pathParameters">Path parameters for the request</param>
74+
public IncidentReportRequestBuilder(Dictionary<string, object> pathParameters) {
75+
_ = pathParameters ?? throw new ArgumentNullException(nameof(pathParameters));
76+
UrlTemplate = "{+baseurl}/admin/serviceAnnouncement/healthOverviews/{serviceHealth%2Did}/issues/{serviceHealthIssue%2Did}/incidentReport()";
77+
var urlTplParams = new Dictionary<string, object>(pathParameters);
78+
PathParameters = urlTplParams;
79+
}
80+
/// <summary>
81+
/// Invoke function incidentReport
82+
/// </summary>
83+
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
84+
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
85+
#nullable enable
86+
public RequestInformation ToGetRequestInformation(Action<IncidentReportRequestBuilderGetRequestConfiguration>? requestConfiguration = default) {
87+
#nullable restore
88+
#else
89+
public RequestInformation ToGetRequestInformation(Action<IncidentReportRequestBuilderGetRequestConfiguration> requestConfiguration = default) {
90+
#endif
91+
var requestInfo = new RequestInformation {
92+
HttpMethod = Method.GET,
93+
UrlTemplate = UrlTemplate,
94+
PathParameters = PathParameters,
95+
};
96+
if (requestConfiguration != null) {
97+
var requestConfig = new IncidentReportRequestBuilderGetRequestConfiguration();
98+
requestConfiguration.Invoke(requestConfig);
99+
requestInfo.AddRequestOptions(requestConfig.Options);
100+
requestInfo.AddHeaders(requestConfig.Headers);
101+
}
102+
return requestInfo;
103+
}
104+
/// <summary>
105+
/// Configuration for the request such as headers, query parameters, and middleware options.
106+
/// </summary>
107+
public class IncidentReportRequestBuilderGetRequestConfiguration {
108+
/// <summary>Request headers</summary>
109+
public RequestHeaders Headers { get; set; }
110+
/// <summary>Request options</summary>
111+
public IList<IRequestOption> Options { get; set; }
112+
/// <summary>
113+
/// Instantiates a new incidentReportRequestBuilderGetRequestConfiguration and sets the default values.
114+
/// </summary>
115+
public IncidentReportRequestBuilderGetRequestConfiguration() {
116+
Options = new List<IRequestOption>();
117+
Headers = new RequestHeaders();
118+
}
119+
}
120+
}
121+
}

0 commit comments

Comments
 (0)