Update README.md

This commit is contained in:
2026-04-15 11:17:51 +02:00
committed by Dev
parent b33c0769d4
commit 6e05d26114
7 changed files with 46 additions and 10 deletions

View File

@@ -19,6 +19,11 @@ public partial class ProfileManagementViewModel : ObservableObject
private readonly ILogger<ProfileManagementViewModel> _logger;
private readonly IAppRegistrationService _appRegistrationService;
// Well-known public client (Microsoft Graph Command Line Tools) used as a bootstrap
// when a profile has no ClientId yet, so the user can sign in as admin and have the
// app registration created for them.
private const string BootstrapClientId = "14d82eec-204b-4c2f-b7e8-296a70dab67e";
[ObservableProperty]
private TenantProfile? _selectedProfile;
@@ -137,7 +142,7 @@ public partial class ProfileManagementViewModel : ObservableObject
{
if (string.IsNullOrWhiteSpace(NewName)) return false;
if (!Uri.TryCreate(NewTenantUrl, UriKind.Absolute, out _)) return false;
if (string.IsNullOrWhiteSpace(NewClientId)) return false;
// ClientId is optional — leaving it blank lets the user register the app from within the tool.
return true;
}
@@ -150,7 +155,7 @@ public partial class ProfileManagementViewModel : ObservableObject
{
Name = NewName.Trim(),
TenantUrl = NewTenantUrl.Trim(),
ClientId = NewClientId.Trim()
ClientId = NewClientId?.Trim() ?? string.Empty
};
await _profileService.AddProfileAsync(profile);
Profiles.Add(profile);
@@ -299,7 +304,14 @@ public partial class ProfileManagementViewModel : ObservableObject
RegistrationStatus = TranslationSource.Instance["profile.register.checking"];
try
{
var isAdmin = await _appRegistrationService.IsGlobalAdminAsync(SelectedProfile.ClientId, ct);
// Use the profile's own ClientId if it has one; otherwise bootstrap with the
// Microsoft Graph Command Line Tools public client so a first-time profile
// (name + URL only) can still perform the admin check and registration.
var authClientId = string.IsNullOrWhiteSpace(SelectedProfile.ClientId)
? BootstrapClientId
: SelectedProfile.ClientId;
var isAdmin = await _appRegistrationService.IsGlobalAdminAsync(authClientId, ct);
if (!isAdmin)
{
ShowFallbackInstructions = true;
@@ -308,11 +320,15 @@ public partial class ProfileManagementViewModel : ObservableObject
}
RegistrationStatus = TranslationSource.Instance["profile.register.registering"];
var result = await _appRegistrationService.RegisterAsync(SelectedProfile.ClientId, SelectedProfile.Name, ct);
var result = await _appRegistrationService.RegisterAsync(authClientId, SelectedProfile.Name, ct);
if (result.IsSuccess)
{
SelectedProfile.AppId = result.AppId;
// If the profile had no ClientId, adopt the freshly registered app's id
// so subsequent sign-ins use the profile's own app registration.
if (string.IsNullOrWhiteSpace(SelectedProfile.ClientId))
SelectedProfile.ClientId = result.AppId!;
await _profileService.UpdateProfileAsync(SelectedProfile);
RegistrationStatus = TranslationSource.Instance["profile.register.success"];
OnPropertyChanged(nameof(HasRegisteredApp));