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

Commit f5b658c

Browse files
committed
Get tenant & client IDs from configuration
1 parent fca773d commit f5b658c

File tree

17 files changed

+199
-31
lines changed

17 files changed

+199
-31
lines changed

.github/workflows/build-cli.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ jobs:
1313
with:
1414
dotnet-version: 6.x
1515
- name: Add NuGet kiota source
16-
# TODO: Add NUGET_USER and NUGET_PASSWORD secrets
17-
# TODO: Add NUGET_URL to env
1816
# NOTE: Password encryption is not supported for the linux platform (Encryption is only supported on Windows platforms.)
1917
run: |
2018
dotnet nuget add source ${{env.NUGET_URL}} -n github -u ${{secrets.NUGET_USER}} -p ${{secrets.NUGET_PASSWORD}} --store-password-in-clear-text

.github/workflows/release-cli.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: "Release CLI"
2+
on: workflow_dispatch # Run manually. Incomplete workflow
3+
jobs:
4+
build-windows:
5+
runs-on: ubuntu-latest
6+
env:
7+
NUGET_URL: https://nuget.pkg.github.com/microsoft/index.json
8+
steps:
9+
- name: Checkout
10+
uses: actions/checkout@v2
11+
- name: Setup .NET Core SDK 6
12+
uses: actions/setup-dotnet@v1
13+
with:
14+
dotnet-version: 6.x
15+
- name: Add NuGet kiota source
16+
# NOTE: Password encryption is not supported for the linux platform (Encryption is only supported on Windows platforms.)
17+
run: |
18+
dotnet nuget add source ${{env.NUGET_URL}} -n github -u ${{secrets.NUGET_USER}} -p ${{secrets.NUGET_PASSWORD}} --store-password-in-clear-text
19+
- uses: actions/cache@v2
20+
with:
21+
path: ~/.nuget/packages
22+
# Look to see if there is a cache hit for the corresponding requirements file
23+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
24+
restore-keys: |
25+
${{ runner.os }}-nuget
26+
- name: Install dependencies
27+
run: dotnet restore
28+
- name: Build
29+
run: dotnet publish --runtime win-x64 --self-contained true --configuration Release --no-restore
30+
build-mac:
31+
runs-on: ubuntu-latest
32+
env:
33+
NUGET_URL: https://nuget.pkg.github.com/microsoft/index.json
34+
steps:
35+
- name: Checkout
36+
uses: actions/checkout@v2
37+
- name: Setup .NET Core SDK 6
38+
uses: actions/setup-dotnet@v1
39+
with:
40+
dotnet-version: 6.x
41+
- name: Add NuGet kiota source
42+
# NOTE: Password encryption is not supported for the linux platform (Encryption is only supported on Windows platforms.)
43+
run: |
44+
dotnet nuget add source ${{env.NUGET_URL}} -n github -u ${{secrets.NUGET_USER}} -p ${{secrets.NUGET_PASSWORD}} --store-password-in-clear-text
45+
- uses: actions/cache@v2
46+
with:
47+
path: ~/.nuget/packages
48+
# Look to see if there is a cache hit for the corresponding requirements file
49+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
50+
restore-keys: |
51+
${{ runner.os }}-nuget
52+
- name: Install dependencies
53+
run: dotnet restore
54+
- name: Build
55+
run: dotnet publish --runtime osx-x64 --self-contained true --configuration Release --no-restore

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,3 +571,6 @@ FodyWeavers.xsd
571571
# Additional files built by Visual Studio
572572

573573
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,visualstudio,intellij+all,dotnetcore,windows,macos,linux
574+
575+
app-settings.*.json
576+
!app-settings.sample.json

.vscode/launch.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"preLaunchTask": "build",
1212
"program": "${workspaceFolder}/src/bin/Debug/net6.0/mgc.dll",
1313
"args": ["-h"],
14-
"cwd": "${workspaceFolder}",
14+
"cwd": "${workspaceFolder}/src",
15+
"envFile": "${workspaceFolder}/src/.env",
1516
"console": "internalConsole",
1617
"stopAtEntry": false
1718
},
@@ -22,7 +23,8 @@
2223
"preLaunchTask": "build",
2324
"program": "${workspaceFolder}/src/bin/Debug/net6.0/mgc.dll",
2425
"args": ["login", "--scopes", "User.ReadWrite Mail.ReadWrite"],
25-
"cwd": "${workspaceFolder}",
26+
"cwd": "${workspaceFolder}/src",
27+
"envFile": "${workspaceFolder}/src/.env",
2628
"console": "internalConsole",
2729
"stopAtEntry": false
2830
},
@@ -33,7 +35,8 @@
3335
"preLaunchTask": "build",
3436
"program": "${workspaceFolder}/src/bin/Debug/net6.0/mgc.dll",
3537
"args": ["me", "get"],
36-
"cwd": "${workspaceFolder}",
38+
"cwd": "${workspaceFolder}/src",
39+
"envFile": "${workspaceFolder}/src/.env",
3740
"console": "internalConsole",
3841
"stopAtEntry": false
3942
},

src/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DOTNET_ENVIRONMENT=Development

src/Authentication/AuthenticationServiceFactory.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,43 @@
33
using System.Threading.Tasks;
44
using Azure.Core;
55
using Azure.Identity;
6+
using Microsoft.Extensions.Options;
7+
using Microsoft.Graph.Cli.Configuration;
8+
using Microsoft.Graph.Cli.IO;
69
using Microsoft.Graph.Cli.Utils;
710

811
namespace Microsoft.Graph.Cli.Authentication;
912

1013
class AuthenticationServiceFactory {
11-
public async Task<ILoginService> GetAuthenticationServiceAsync(AuthenticationStrategy strategy) {
14+
public async Task<ILoginService> GetAuthenticationServiceAsync(AuthenticationStrategy strategy, string tenantId, string clientId) {
1215
switch (strategy) {
1316
case AuthenticationStrategy.DeviceCode:
14-
return await GetDeviceCodeLoginServiceAsync();
17+
return await GetDeviceCodeLoginServiceAsync(tenantId, clientId);
1518
default:
1619
throw new InvalidOperationException($"The authentication strategy {strategy} is not supported");
1720
}
1821

1922
}
2023

21-
public async Task<TokenCredential> GetTokenCredentialAsync(AuthenticationStrategy strategy) {
24+
public async Task<TokenCredential> GetTokenCredentialAsync(AuthenticationStrategy strategy, string tenantId, string clientId) {
2225
switch (strategy) {
2326
case AuthenticationStrategy.DeviceCode:
24-
return await GetDeviceCodeCredentialAsync();
27+
return await GetDeviceCodeCredentialAsync(tenantId, clientId);
2528
default:
2629
throw new InvalidOperationException($"The authentication strategy {strategy} is not supported");
2730
}
2831
}
2932

30-
private async Task<DeviceCodeLoginService> GetDeviceCodeLoginServiceAsync() {
31-
var credential = await GetDeviceCodeCredentialAsync();
32-
return new(credential);
33+
private async Task<DeviceCodeLoginService> GetDeviceCodeLoginServiceAsync(string tenantId, string clientId) {
34+
var credential = await GetDeviceCodeCredentialAsync(tenantId, clientId);
35+
return new(credential, new PathUtility());
3336
}
3437

35-
private async Task<DeviceCodeCredential> GetDeviceCodeCredentialAsync() {
38+
private async Task<DeviceCodeCredential> GetDeviceCodeCredentialAsync(string tenantId, string clientId) {
3639
DeviceCodeCredentialOptions credOptions = new()
3740
{
38-
ClientId = Constants.ClientId,
39-
TenantId = Constants.TenantId
41+
ClientId = clientId,
42+
TenantId = tenantId,
4043
};
4144

4245
TokenCachePersistenceOptions tokenCacheOptions = new() { Name = Constants.TokenCacheName };

src/Authentication/DeviceCodeLoginService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Azure.Core;
22
using Azure.Identity;
3+
using Microsoft.Graph.Cli.IO;
34
using Microsoft.Graph.Cli.Utils;
45
using System.IO;
56
using System.Threading.Tasks;
@@ -9,7 +10,7 @@ namespace Microsoft.Graph.Cli.Authentication;
910
class DeviceCodeLoginService : LoginServiceBase {
1011
private DeviceCodeCredential credential;
1112

12-
public DeviceCodeLoginService(DeviceCodeCredential credential) {
13+
public DeviceCodeLoginService(DeviceCodeCredential credential, IPathUtility pathUtility) : base(pathUtility) {
1314
this.credential = credential;
1415
}
1516

src/Authentication/LoginServiceBase.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,18 @@
22
using System.IO;
33
using System.Threading.Tasks;
44
using Azure.Identity;
5+
using Microsoft.Graph.Cli.IO;
56
using Microsoft.Graph.Cli.Utils;
67

78
namespace Microsoft.Graph.Cli.Authentication;
89

910
abstract class LoginServiceBase : ILoginService {
11+
private readonly IPathUtility pathUtility;
12+
13+
protected LoginServiceBase(IPathUtility pathUtility) {
14+
this.pathUtility = pathUtility;
15+
}
16+
1017
public async Task LoginAsync(string[] scopes) {
1118
var record = await this.DoLoginAsync(scopes);
1219
await this.SaveSessionAsync(record);
@@ -15,7 +22,7 @@ public async Task LoginAsync(string[] scopes) {
1522
protected abstract Task<AuthenticationRecord> DoLoginAsync(string[] scopes);
1623

1724
public async Task SaveSessionAsync(AuthenticationRecord record) {
18-
var homeDir = Environment.GetEnvironmentVariable("HOME") ?? Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
25+
var homeDir = pathUtility.GetUserHomeDirectory();
1926
var recordPath = Path.Combine(homeDir, Constants.ApplicationDataDirectory, Constants.AuthRecordPath);
2027
using var authRecordStream = new FileStream(recordPath, FileMode.OpenOrCreate, FileAccess.Write);
2128
await record.SerializeAsync(authRecordStream);

src/Commands/Authentication/LoginCommand.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.Hosting;
3+
using Microsoft.Extensions.Options;
14
using Microsoft.Graph.Cli.Authentication;
5+
using Microsoft.Graph.Cli.Configuration;
26
using Microsoft.Graph.Cli.Utils;
37
using System.CommandLine;
48
using System.CommandLine.Invocation;
@@ -23,9 +27,10 @@ public Command Build() {
2327
var strategy = new Option<AuthenticationStrategy>("--strategy", () => Constants.defaultAuthStrategy, "The authentication strategy to use.");
2428
loginCommand.AddOption(strategy);
2529

26-
loginCommand.Handler = CommandHandler.Create<string[], AuthenticationStrategy>(async (scopes, strategy) =>
30+
loginCommand.Handler = CommandHandler.Create<string[], AuthenticationStrategy, IHost>(async (scopes, strategy, host) =>
2731
{
28-
var authService = await this.authenticationServiceFactory.GetAuthenticationServiceAsync(strategy);
32+
var options = host.Services.GetRequiredService<IOptionsMonitor<AuthenticationOptions>>().CurrentValue;
33+
var authService = await this.authenticationServiceFactory.GetAuthenticationServiceAsync(strategy, options?.TenantId, options?.ClientId);
2934
await authService.LoginAsync(scopes);
3035
});
3136

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Microsoft.Graph.Cli.Configuration;
2+
3+
public class AuthenticationOptions {
4+
public string TenantId { get; set; }
5+
6+
public string ClientId { get; set; }
7+
}

0 commit comments

Comments
 (0)