diff --git a/src/AzureAdB2C/.vscode/launch.json b/src/AzureAdB2C/.vscode/launch.json deleted file mode 100644 index 448ee2b7..00000000 --- a/src/AzureAdB2C/.vscode/launch.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - // Use IntelliSense to find out which attributes exist for C# debugging - // Use hover for the description of the existing attributes - // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md. - "name": ".NET Core Launch (AzureADB2C Claims Populator/Validator)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "Build AzureADB2C Claims Populator/Validator", - // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/Testing/bin/Local/net8.0/Dgmjr.AzureAdB2C.Testing.dll", - "args": [], - "cwd": "${workspaceFolder}/Testing", - "stopAtEntry": false, - // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "sourceFileMap": { - "/Views": "${workspaceFolder}/Views" - } - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach" - } - ] -} diff --git a/src/AzureAdB2C/.vscode/tasks.json b/src/AzureAdB2C/.vscode/tasks.json deleted file mode 100644 index 5413421c..00000000 --- a/src/AzureAdB2C/.vscode/tasks.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Build AzureADB2C Claims Populator/Validator", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/Testing/Dgmjr.AzureAdB2C.Testing.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary;ForceNoAlign", - "-c:Local", - "-p:BuildFromSource=false" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "Launch ngrok (Dgmjr.AzureAdB2C.Testing)", - "command": "ngrok", - "type": "process", - "args": [ - "tunnel", - "--label", - "edge=edghts_2YVlve6yoIHeHG4dzj3cV1Ojnqn", - "https://localhost:7162" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/Testing/Dgmjr.AzureAdB2C.Testing.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary;ForceNoAlign", - "-c:Local", - "-p:BuildFromSource=false" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "--project", - "${workspaceFolder}/Testing/Dgmjr.AzureAdB2C.Testing.csproj" - ], - "problemMatcher": "$msCompile" - } - ] -} diff --git a/src/AzureAdB2C/Api/AppRolesGeneratorApi.cs b/src/AzureAdB2C/Api/AppRolesGeneratorApi.cs deleted file mode 100644 index 4def083b..00000000 --- a/src/AzureAdB2C/Api/AppRolesGeneratorApi.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Api; -using Microsoft.AspNetCore.Authorization; -using Dgmjr.AzureAdB2C.Services.Graph; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; -using Dgmjr.AzureAdB2C.Models; - -public class AppRolesGeneratorApi(ILogger logger, IAppRolesService appRolesService) : ApiControllerBase(logger) -{ - [Authorize] - [HttpPost] - [Route("api/approles/generate")] - [Consumes("application/json")] - public async Task GenerateAsync([FromBody] ApiRequest request, CancellationToken cancellationToken = default) - { - // var request = Deserialize(requestJson); - logger.LogDebug("request: {request}", request); - var result = await appRolesService.GenerateClaimsAsync(request, cancellationToken); - - return result.StatusCode switch - { - StatusCodes.Status200OK => Ok(result), - StatusCodes.Status400BadRequest => BadRequest(result), - StatusCodes.Status401Unauthorized => Unauthorized(result), - StatusCodes.Status403Forbidden => Forbid((result as ApiBlockResponse)!.UserMessage), - StatusCodes.Status404NotFound => NotFound(result), - StatusCodes.Status409Conflict => Conflict(result), - StatusCodes.Status500InternalServerError => Problem((result as ApiErrorResponse)!.DeveloperMessage, statusCode: result.StatusCode), - _ => StatusCode(result.StatusCode ?? StatusCodes.Status200OK, result), - }; - } -} diff --git a/src/AzureAdB2C/Api/ClaimsGeneratorApi.cs b/src/AzureAdB2C/Api/ClaimsGeneratorApi.cs deleted file mode 100644 index 4f67a89c..00000000 --- a/src/AzureAdB2C/Api/ClaimsGeneratorApi.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Api; - -using Dgmjr.AspNetCore.Controllers; -using Dgmjr.AzureAdB2C.Models; -using Dgmjr.AzureAdB2C.Services; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; - -public abstract class ClaimsGeneratorApi( - ILogger logger, - IClaimsGenerator claimsGenerator, - IUserHydrator userHydrator -) : ApiControllerBase(logger) -{ - public virtual IClaimsGenerator ClaimsGenerator => claimsGenerator; - public virtual IUserHydrator UserHydrator => userHydrator; - - [HttpPost] - [Route("api/claims/validate")] - public async Task ValidateAsync( - [FromBody] ApiRequest request, - CancellationToken cancellationToken = default - ) - { - var result = await ClaimsGenerator.GenerateClaimsAsync( - request, - cancellationToken - ); - - return result.StatusCode switch - { - StatusCodes.Status200OK => Ok(result), - StatusCodes.Status400BadRequest => BadRequest(result), - StatusCodes.Status401Unauthorized => Unauthorized(result), - StatusCodes.Status403Forbidden => Forbid((result as ApiBlockResponse)!.UserMessage), - StatusCodes.Status404NotFound => NotFound(result), - StatusCodes.Status409Conflict => Conflict(result), - StatusCodes.Status500InternalServerError => Problem((result as ApiErrorResponse)!.DeveloperMessage, statusCode: result.StatusCode), - _ => StatusCode(result.StatusCode ?? StatusCodes.Status200OK, result), - }; - } -} diff --git a/src/AzureAdB2C/Api/ClaimsValidatorApi.cs b/src/AzureAdB2C/Api/ClaimsValidatorApi.cs deleted file mode 100644 index c549d927..00000000 --- a/src/AzureAdB2C/Api/ClaimsValidatorApi.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Api; - -using Dgmjr.AspNetCore.Controllers; -using Dgmjr.AzureAdB2C.Models; -using Dgmjr.AzureAdB2C.Services; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; - - -public abstract class ClaimsValidatorApi( - ILogger logger, - IClaimsValidator claimsValidator -) : ApiControllerBase(logger) -{ - public virtual IClaimsValidator ClaimsValidator => claimsValidator; - - [HttpPost] - [Route("api/claims/generate")] - public async Task GenerateAsync( - [FromBody] ApiRequest request, - CancellationToken cancellationToken = default - ) - { - var result = await ClaimsValidator.ValidateAsync(request, cancellationToken); - - if(IsNullOrWhiteSpace(result.ErrorMessage)) - { - var response = new ApiContinueResponse { Version = ClaimsValidator.Version }; - return Ok(response); - } - else - { - var response = new ApiValidationErrorResponse(result.ErrorMessage) { Version = ClaimsValidator.Version }; - return BadRequest(response); - } - } -} diff --git a/src/AzureAdB2C/Api/Dgmjr.AzureAdB2C.Api.csproj b/src/AzureAdB2C/Api/Dgmjr.AzureAdB2C.Api.csproj deleted file mode 100644 index 0e80fc67..00000000 --- a/src/AzureAdB2C/Api/Dgmjr.AzureAdB2C.Api.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - - net6.0;net8.0 - - - - - - - - - - - - - - diff --git a/src/AzureAdB2C/Api/Dgmjr.AzureAdB2C.Api.sln b/src/AzureAdB2C/Api/Dgmjr.AzureAdB2C.Api.sln deleted file mode 100644 index 49352a4a..00000000 --- a/src/AzureAdB2C/Api/Dgmjr.AzureAdB2C.Api.sln +++ /dev/null @@ -1,84 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" - ProjectSection(SolutionItems) = preProject - ..\..\..\Directory.Build.props = ..\..\..\Directory.Build.props - ..\..\..\..\..\Directory.Build.targets = ..\..\..\..\..\Directory.Build.targets - ..\..\..\..\..\global.json = ..\..\..\..\..\global.json - ..\..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\..\Packages\Versions.Local.props - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Web.DownstreamApis", "..\..\DownstreamApis\Dgmjr.Web.DownstreamApis.csproj", "{0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Graph", "..\..\MicrosoftGraph\Dgmjr.Graph.csproj", "{FD458274-EBF4-4E98-9E7C-5D93DA648AEA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.AzureAdB2C.Services", "..\Services\Dgmjr.AzureAdB2C.Services.csproj", "{32AD2745-C108-4DC1-8681-44F5318E4BF0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.AzureAdB2C.Api", "Dgmjr.AzureAdB2C.Api.csproj", "{AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Local|Any CPU = Local|Any CPU - Debug|Any CPU = Debug|Any CPU - Testing|Any CPU = Testing|Any CPU - Staging|Any CPU = Staging|Any CPU - Production|Any CPU = Production|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Local|Any CPU.ActiveCfg = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Local|Any CPU.Build.0 = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Testing|Any CPU.Build.0 = Testing|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Staging|Any CPU.Build.0 = Staging|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Production|Any CPU.ActiveCfg = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Production|Any CPU.Build.0 = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Release|Any CPU.Build.0 = Release|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Local|Any CPU.ActiveCfg = Local|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Local|Any CPU.Build.0 = Local|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Testing|Any CPU.Build.0 = Testing|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Staging|Any CPU.Build.0 = Staging|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Production|Any CPU.ActiveCfg = Local|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Production|Any CPU.Build.0 = Local|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FD458274-EBF4-4E98-9E7C-5D93DA648AEA}.Release|Any CPU.Build.0 = Release|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Local|Any CPU.ActiveCfg = Local|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Local|Any CPU.Build.0 = Local|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Testing|Any CPU.Build.0 = Testing|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Staging|Any CPU.Build.0 = Staging|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Production|Any CPU.ActiveCfg = Local|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Production|Any CPU.Build.0 = Local|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {32AD2745-C108-4DC1-8681-44F5318E4BF0}.Release|Any CPU.Build.0 = Release|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Local|Any CPU.ActiveCfg = Local|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Local|Any CPU.Build.0 = Local|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Testing|Any CPU.Build.0 = Testing|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Staging|Any CPU.Build.0 = Staging|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Production|Any CPU.ActiveCfg = Local|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Production|Any CPU.Build.0 = Local|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AA8E3890-CD65-4B80-AD09-C3A1ED9D7523}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {2D8AB580-E186-48E6-BED8-53D6A4941986} - EndGlobalSection -EndGlobal diff --git a/src/AzureAdB2C/Services/ClaimsGenerator.cs b/src/AzureAdB2C/Services/ClaimsGenerator.cs deleted file mode 100644 index bc9bcc91..00000000 --- a/src/AzureAdB2C/Services/ClaimsGenerator.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Services; - -using System.Security.Claims; - -using Dgmjr.AzureAdB2C.Models; - -using Microsoft.Extensions.Options; - -public interface IClaimsGenerator -{ - Task GenerateClaimsAsync( - ApiRequest request, - CancellationToken cancellationToken = default - ); - Version Version { get; } -} - -public abstract class ClaimsGenerator(IOptions version) : IClaimsGenerator -{ - public virtual Version Version => version.Value; - public abstract Task GenerateClaimsAsync( - ApiRequest request, - CancellationToken cancellationToken = default - ); -} diff --git a/src/AzureAdB2C/Services/ClaimsValidator.cs b/src/AzureAdB2C/Services/ClaimsValidator.cs deleted file mode 100644 index 0668532c..00000000 --- a/src/AzureAdB2C/Services/ClaimsValidator.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Services; - -using System.ComponentModel.DataAnnotations; -using System.Security.Claims; - -using Dgmjr.AzureAdB2C.Models; - -using Microsoft.Extensions.Options; - -public interface IClaimsValidator -{ - Task ValidateAsync( - ApiRequest request, - CancellationToken cancellationToken = default - ); - Version Version { get; } -} - -public class ClaimsValidatorOptions -{ - public virtual Version Version { get; set; } = default!; - public virtual Func ValidateClaim { get; set; } = kvp => ValidationResult.Success; - - public virtual ValidationResult Validate(StrKvp kvp) => ValidateClaim(kvp); - - public virtual ValidationResult Validate(ApiRequest request) - { - var results = request.Select(Validate); - var failures = results.Where(result => !IsNullOrWhiteSpace(result.ErrorMessage)); - var messages = failures.Select(result => $"{Join(", ", result.MemberNames)}: {result.ErrorMessage}"); - var message = Join(env.NewLine, messages); - return (failures.Any() ? new ValidationResult(message, failures.SelectMany(result => result.MemberNames)) : ValidationResult.Success)!; - } -} - -public abstract class ClaimsValidator(IOptions options) : IClaimsValidator -{ - public Version Version => options.Value.Version; - public abstract Task ValidateAsync( - ApiRequest request, - CancellationToken cancellationToken = default - ); -} diff --git a/src/AzureAdB2C/Services/Dgmjr.AzureAdB2C.Services.csproj b/src/AzureAdB2C/Services/Dgmjr.AzureAdB2C.Services.csproj deleted file mode 100644 index 933fe4d2..00000000 --- a/src/AzureAdB2C/Services/Dgmjr.AzureAdB2C.Services.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - - net6.0;net8.0 - - - - - - - - - - - - - - diff --git a/src/AzureAdB2C/Services/Dgmjr.AzureAdB2C.Services.sln b/src/AzureAdB2C/Services/Dgmjr.AzureAdB2C.Services.sln deleted file mode 100644 index aca64e77..00000000 --- a/src/AzureAdB2C/Services/Dgmjr.AzureAdB2C.Services.sln +++ /dev/null @@ -1,70 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" - ProjectSection(SolutionItems) = preProject - ..\..\..\Directory.Build.props = ..\..\..\Directory.Build.props - ..\..\..\..\..\Directory.Build.targets = ..\..\..\..\..\Directory.Build.targets - ..\..\..\..\..\global.json = ..\..\..\..\..\global.json - ..\..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\..\Packages\Versions.Local.props - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Web.DownstreamApis", "..\..\DownstreamApis\Dgmjr.Web.DownstreamApis.csproj", "{0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Graph", "..\..\MicrosoftGraph\Dgmjr.Graph.csproj", "{630E503A-45AE-4D8C-A35F-3E499810DF91}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.AzureAdB2C.Services", "Dgmjr.AzureAdB2C.Services.csproj", "{3CBB5BC6-4C01-4708-894C-37DFCB8523D1}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Local|Any CPU = Local|Any CPU - Debug|Any CPU = Debug|Any CPU - Testing|Any CPU = Testing|Any CPU - Staging|Any CPU = Staging|Any CPU - Production|Any CPU = Production|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Local|Any CPU.ActiveCfg = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Local|Any CPU.Build.0 = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Testing|Any CPU.Build.0 = Testing|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Staging|Any CPU.Build.0 = Staging|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Production|Any CPU.ActiveCfg = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Production|Any CPU.Build.0 = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Release|Any CPU.Build.0 = Release|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Local|Any CPU.ActiveCfg = Local|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Local|Any CPU.Build.0 = Local|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Testing|Any CPU.Build.0 = Testing|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Staging|Any CPU.Build.0 = Staging|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Production|Any CPU.ActiveCfg = Local|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Production|Any CPU.Build.0 = Local|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {630E503A-45AE-4D8C-A35F-3E499810DF91}.Release|Any CPU.Build.0 = Release|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Local|Any CPU.ActiveCfg = Local|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Local|Any CPU.Build.0 = Local|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Testing|Any CPU.Build.0 = Testing|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Staging|Any CPU.Build.0 = Staging|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Production|Any CPU.ActiveCfg = Local|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Production|Any CPU.Build.0 = Local|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3CBB5BC6-4C01-4708-894C-37DFCB8523D1}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {CCAFD427-35E6-4064-B3B6-7E7AFCF69FC1} - EndGlobalSection -EndGlobal diff --git a/src/AzureAdB2C/Services/Graph/AppRolesService.cs b/src/AzureAdB2C/Services/Graph/AppRolesService.cs deleted file mode 100644 index ff3d907d..00000000 --- a/src/AzureAdB2C/Services/Graph/AppRolesService.cs +++ /dev/null @@ -1,167 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Services.Graph; - -using System; -using System.Security.Claims; - -using Dgmjr.AzureAdB2C.Models; -using Dgmjr.Graph.Constants; -using Dgmjr.Graph.Options; -using Dgmjr.Graph.Services; -using Dgmjr.Graph.TokenProviders; -using Dgmjr.AspNetCore.Authentication.Basic; - -using Microsoft.Extensions.Options; -using Microsoft.Graph; -using System.Net.Http.Headers; -using Microsoft.Identity.Client; - -public interface IAppRolesService -{ - Version Version { get; } - - Task GenerateClaimsAsync( - ApiRequest request, - CancellationToken cancellationToken = default - ); -} - -public class AppRolesService( - IOptionsMonitor msidOptions, - IOptions version, - IOptions graphClientOptions, - GraphServiceClient graph, - ILogger logger -) : IClaimsGenerator, IAppRolesService, ILog -{ - public ILogger Logger => logger; - private readonly Dgmjr.AzureAd.Web.MicrosoftIdentityOptions _msidOptions = - msidOptions.CurrentValue; - public Version Version => version.Value; - - private string clientId => _msidOptions.ClientId; - private string clientSecret => _msidOptions.ClientSecret; - private string tenantId => _msidOptions.TenantId; - - private GraphServiceClient _graph; - private GraphServiceClient Graph => _graph ??= GetGraphServiceClient().Result; - - private readonly AzureAdB2CGraphOptions _graphClientOptions = graphClientOptions.Value; - - public async Task GenerateClaimsAsync( - ApiRequest request, - CancellationToken cancellationToken = default - ) - { - Logger.LogDebug("request: {request}", request); - - var app = await Graph.Applications[ - _graphClientOptions.AzureAdB2CExtensionsApplicationId.ToString() - ] - .Request() - .GetAsync(cancellationToken); - Logger.LogDebug("app: {app}", app); - - var user = await Graph.Users[request.ObjectId.ToString()] - // .Request(new Option[] { new QueryOption("$expand", "appRoleAssignments") }) - .Request() - .Expand("appRoleAssignments") - .GetAsync(cancellationToken); - Logger.LogDebug("user: {user}", user); - - var appRoles = app.AppRoles; - var myAppRoles = user.AppRoleAssignments - .Where(x => x.ResourceId == _graphClientOptions.AzureAdB2CExtensionsApplicationId) - .ToList(); - var myAppsAppRoles = myAppRoles.Select( - appRole => appRoles.FirstOrDefault(x => x.Id.ToString() == appRole.Id) - ); - return new ApiContinueResponse - { - Claims = new StringDictionary() { { ClaimTypes.Role, Serialize(myAppsAppRoles) } }, - Version = Version - }; - } - - - private async Task GetGraphServiceClient() - { - var app = ConfidentialClientApplicationBuilder - .Create(clientId) - .WithClientSecret(clientSecret) - .WithAuthority($"https://login.microsoftonline.com/{tenantId}") - .Build(); - - var authResult = await app.AcquireTokenForClient(new[] { "https://graph.microsoft.com/.default" }) - .ExecuteAsync(); - - var graphClient = new GraphServiceClient( - new DelegateAuthenticationProvider((requestMessage) => - { - requestMessage.Headers.Authorization = - new AuthenticationHeaderValue("Bearer", authResult.AccessToken); - - return Task.CompletedTask; - })); - return graphClient; - } - - - // public static async Task> GetApplicationRolesForUserAsync(string userId) - // { - // var applicationRoles = new List(); - - // var app = ConfidentialClientApplicationBuilder - // .Create(clientId) - // .WithClientSecret(clientSecret) - // .WithAuthority($"https://login.microsoftonline.com/{tenantId}") - // .Build(); - - // var authResult = await app.AcquireTokenForClient(new[] { "https://graph.microsoft.com/.default" }) - // .ExecuteAsync(); - - // var graphClient = new GraphServiceClient( - // new DelegateAuthenticationProvider((requestMessage) => - // { - // requestMessage.Headers.Authorization = - // new AuthenticationHeaderValue("Bearer", authResult.AccessToken); - - // return Task.CompletedTask; - // })); - - // try - // { - // // Query Microsoft Graph to get the user's assigned directory roles - // var userDirectoryRoles = await graphClient.Users[userId].MemberOf.Request().GetAsync(); - - // foreach (var directoryRole in userDirectoryRoles.OfType()) - // { - // // Query each directory role to get its assigned application roles - // var applicationRoleAssignments = await graphClient.DirectoryRoles[directoryRole.Id].AppRoleAssignedTo.Request().GetAsync(); - - // foreach (var applicationRoleAssignment in applicationRoleAssignments) - // { - // applicationRoles.Add(applicationRoleAssignment.AppRoleId); - // } - // } - // } - // catch (ServiceException ex) - // { - // Console.WriteLine($"Error retrieving application roles: {ex.Message}"); - // } - - // return applicationRoles; - // } - - // public static async Task Main(string[] args) - // { - // string userId = "user_id_goes_here"; - // List applicationRoles = await GetApplicationRolesForUserAsync(userId); - - // // Print the application roles for the user - // foreach (var role in applicationRoles) - // { - // Console.WriteLine(role); - // } - // } - // } -} diff --git a/src/AzureAdB2C/Services/LICENSE.md b/src/AzureAdB2C/Services/LICENSE.md deleted file mode 100644 index 4f592f86..00000000 --- a/src/AzureAdB2C/Services/LICENSE.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -date: 2023-07-13T05:44:46:00-05:00Z -description: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files, yadda, yadda, yadda... -keywords: -- IP -- copyright -- license -- mit -permissions: -- commercial-use -- modifications -- distribution -- private-use -conditions: -- include-copyright -limitations: -- liability -- warranty -lastmod: 2024-01-0T00:39:00.0000+05:00Z -license: MIT -slug: mit-license -title: MIT License -type: license ---- - -# MIT License - -## Copyright © 2022-2024 [David G. Moore, Jr.](mailto:david@dgmjr.io "Send Dr. Moore") ([@dgmjr](https://github.com/dgmjr "Contact Dr. Moore on GitHub")), All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/src/AzureAdB2C/Services/Models/ApiRequest.cs b/src/AzureAdB2C/Services/Models/ApiRequest.cs deleted file mode 100644 index dc0f6278..00000000 --- a/src/AzureAdB2C/Services/Models/ApiRequest.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Models; - -using System.Globalization; - -public class ApiRequest : StringDictionary -{ - public string? Email { get; set; } - public ICollection? Identities { get; set; } = new List(); - public guid ClientId { get; set; } - public guid ObjectId { get; set; } - public string Step { get; set; } = default!; - - [JsonConverter(typeof(JsonLocaleConverter))] - public CultureInfo? UiLocales { get; set; } -} - -public class UserIdentity -{ - public string SignInType { get; set; } = default!; - public string Issuer { get; set; } = default!; - public string IssuerAssignedId { get; set; } = default!; -} diff --git a/src/AzureAdB2C/Services/Models/ApiResponse.cs b/src/AzureAdB2C/Services/Models/ApiResponse.cs deleted file mode 100644 index b74971ca..00000000 --- a/src/AzureAdB2C/Services/Models/ApiResponse.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Dgmjr.AzureAdB2C.Json; - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Infrastructure; - -namespace Dgmjr.AzureAdB2C.Models; - -public abstract class ApiResponse : ActionResult, IStatusCodeActionResult -{ - [JIgnore] - public virtual bool IsSuccess => Action == ApiResponseAction.Continue; - [JProp("version")] - public virtual Version Version { get; set; } = default!; - [JProp("action")] - public virtual ApiResponseAction Action => ApiResponseAction.Continue; - [JProp("status")] - public virtual int? StatusCode => StatusCodes.Status200OK; -} - -[JsonConverter(typeof(JsonApiContinueResponseConverter))] -public class ApiContinueResponse : ApiResponse -{ - public override ApiResponseAction Action => ApiResponseAction.Continue; - - public virtual IStringDictionary Claims { get; set; } = new StringDictionary(); -} - -public abstract class ApiErrorResponse(string userMessage, string? developerMessage = default) - : ApiResponse -{ - public virtual string? UserMessage => userMessage; - public virtual string? DeveloperMessage => developerMessage ?? userMessage; -} - -public class ApiBlockResponse(string userMessage, string? developerMessage = default) - : ApiErrorResponse(userMessage, developerMessage) -{ - public override ApiResponseAction Action => ApiResponseAction.ShowBlockPage; -} - -public class ApiValidationErrorResponse( - string userMessage, - string? developerMessage = default -) : ApiErrorResponse(userMessage, developerMessage) -{ - public override int? StatusCode => StatusCodes.Status400BadRequest; - public override ApiResponseAction Action => ApiResponseAction.ValidationError; -} - -[JsonConverter(typeof(JStringEnumConverter))] -public enum ApiResponseAction -{ - Continue, - ShowBlockPage, - Redirect, - ValidationError -} diff --git a/src/AzureAdB2C/Services/Models/JsonApiContinueResponseConverter.cs b/src/AzureAdB2C/Services/Models/JsonApiContinueResponseConverter.cs deleted file mode 100644 index de948cac..00000000 --- a/src/AzureAdB2C/Services/Models/JsonApiContinueResponseConverter.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Json; -using System; -using System.Text.Json; - -using Dgmjr.AzureAdB2C.Models; - -using Microsoft.AspNetCore.Http; -public class JsonApiContinueResponseConverter : JsonConverter -{ - public override ApiContinueResponse? Read(ref Utf8JsonReader reader, type typeToConvert, Jso options) - { - throw new NotImplementedException("This converter is only for writing"); - } - - public override void Write(Utf8JsonWriter writer, ApiContinueResponse value, Jso options) - { - writer.WriteStartObject(); - writer.WriteString("version", value.Version.ToString()); - writer.WriteString("action", value.Action.ToString()); - writer.WriteNumber("status", value.StatusCode ?? StatusCodes.Status200OK); - foreach(var (claimType, claimValue) in value.Claims) - { - writer.WriteString(claimType, claimValue); - } - writer.WriteEndObject(); - } -} diff --git a/src/AzureAdB2C/Services/UserHydrator.cs b/src/AzureAdB2C/Services/UserHydrator.cs deleted file mode 100644 index 412cda35..00000000 --- a/src/AzureAdB2C/Services/UserHydrator.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Dgmjr.AzureAdB2C.Services; - -using System.Security.Claims; - -using Microsoft.AspNetCore.Http; - -public interface IUserHydrator -{ - Task HydrateAsync(HttpContext context, ClaimsPrincipal principal, CancellationToken cancellationToken = default); -} - -public class UserHydrator : IUserHydrator -{ - public virtual Task HydrateAsync( - HttpContext context, - ClaimsPrincipal principal, - CancellationToken cancellationToken = default - ) - { - - return Task.FromResult(principal); - } -} diff --git a/src/AzureAdB2C/Services/icon.png b/src/AzureAdB2C/Services/icon.png deleted file mode 100644 index db07a039..00000000 Binary files a/src/AzureAdB2C/Services/icon.png and /dev/null differ diff --git a/src/AzureAdB2C/api-connector-samples b/src/AzureAdB2C/api-connector-samples deleted file mode 160000 index 5e56afe5..00000000 --- a/src/AzureAdB2C/api-connector-samples +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5e56afe56885a37264271ba670521abcaf5fda83 diff --git a/src/Blazor/Component1.razor b/src/Blazor/Component1.razor new file mode 100644 index 00000000..ac2882b7 --- /dev/null +++ b/src/Blazor/Component1.razor @@ -0,0 +1,3 @@ +
+ This component is defined in the Dgmjr.AspNetCore.Razor.Components library. +
diff --git a/src/Blazor/Component1.razor.css b/src/Blazor/Component1.razor.css new file mode 100644 index 00000000..757bfd36 --- /dev/null +++ b/src/Blazor/Component1.razor.css @@ -0,0 +1,6 @@ +.my-component { + border: 2px dashed red; + padding: 1em; + margin: 1em 0; + background-image: url('background.png'); +} diff --git a/src/Blazor/Dgmjr.Razor.Components.csproj b/src/Blazor/Dgmjr.Razor.Components.csproj new file mode 100644 index 00000000..af07f655 --- /dev/null +++ b/src/Blazor/Dgmjr.Razor.Components.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + + diff --git a/src/Blazor/ExampleJsInterop.cs b/src/Blazor/ExampleJsInterop.cs new file mode 100644 index 00000000..b14e97df --- /dev/null +++ b/src/Blazor/ExampleJsInterop.cs @@ -0,0 +1,36 @@ +using Microsoft.JSInterop; + +namespace Dgmjr.AspNetCore.Razor.Components; + +// This class provides an example of how JavaScript functionality can be wrapped +// in a .NET class for easy consumption. The associated JavaScript module is +// loaded on demand when first needed. +// +// This class can be registered as scoped DI service and then injected into Blazor +// components for use. + +public class ExampleJsInterop : IAsyncDisposable +{ + private readonly Lazy> moduleTask; + + public ExampleJsInterop(IJSRuntime jsRuntime) + { + moduleTask = new (() => jsRuntime.InvokeAsync( + "import", "./_content/Dgmjr.AspNetCore.Razor.Components/exampleJsInterop.js").AsTask()); + } + + public async ValueTask Prompt(string message) + { + var module = await moduleTask.Value; + return await module.InvokeAsync("showPrompt", message); + } + + public async ValueTask DisposeAsync() + { + if (moduleTask.IsValueCreated) + { + var module = await moduleTask.Value; + await module.DisposeAsync(); + } + } +} diff --git a/src/AzureAdB2C/Api/LICENSE.md b/src/Blazor/LICENSE.md similarity index 100% rename from src/AzureAdB2C/Api/LICENSE.md rename to src/Blazor/LICENSE.md diff --git a/src/Blazor/NavBrand.razor b/src/Blazor/NavBrand.razor new file mode 100644 index 00000000..d30d9fd6 --- /dev/null +++ b/src/Blazor/NavBrand.razor @@ -0,0 +1,20 @@ +@namespace Dgmjr.Razor.Components + + + @ImgAlt + @ChildContent + @Title + + +@code { + [Parameter] public string Href { get; set; } = "#"; + + [Parameter] public RenderFragment ChildContent { get; set; } + + [Parameter] public string ImgSrc { get; set; } = ""; + + private string? _imgAlt; + [Parameter] public string ImgAlt { get => _imgAlt ??= Title; set => _imgAlt = value; } + + [Parameter] public string Title { get; set; } = ""; +} diff --git a/src/Blazor/_Imports.razor b/src/Blazor/_Imports.razor new file mode 100644 index 00000000..dc10de73 --- /dev/null +++ b/src/Blazor/_Imports.razor @@ -0,0 +1 @@ +@using Microsoft.AspNetCore.Components.Web diff --git a/src/AzureAdB2C/Api/icon.png b/src/Blazor/icon.png similarity index 100% rename from src/AzureAdB2C/Api/icon.png rename to src/Blazor/icon.png diff --git a/src/Blazor/src/JSInterop.ts b/src/Blazor/src/JSInterop.ts new file mode 100644 index 00000000..b98849f5 --- /dev/null +++ b/src/Blazor/src/JSInterop.ts @@ -0,0 +1,6 @@ +import { DotNet } from '@microsoft/dotnet-js-interop'; +export const JSInterop = { + invokeDotNetMethod: (method: string, ...args: any[]) => { + return DotNet.invokeMethodAsync('BlazorApp', method, ...args); + } +} diff --git a/src/Blazor/src/package-lock.json b/src/Blazor/src/package-lock.json new file mode 100644 index 00000000..13f59a5d --- /dev/null +++ b/src/Blazor/src/package-lock.json @@ -0,0 +1,11 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@microsoft/dotnet-js-interop": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@microsoft/dotnet-js-interop/-/dotnet-js-interop-8.0.0.tgz", + "integrity": "sha512-REgH1LzhP68m3i8B80KLyKLRIOhLbWjwGl60HyVQEqN2eDeFUlgRfjifMa+Udl/NpIIafjqslMAouV8BUzHm8Q==" + } + } +} diff --git a/src/Blazor/src/package.json b/src/Blazor/src/package.json new file mode 100644 index 00000000..5692bf1c --- /dev/null +++ b/src/Blazor/src/package.json @@ -0,0 +1,9 @@ +{ + "author": { + "name": "David G. Moore, Jr.", + "email": "david@dgmjr.io" + }, + "dependencies": { + "@microsoft/dotnet-js-interop": "^8.0.0" + } +} diff --git a/src/Blazor/src/tsconfig.json b/src/Blazor/src/tsconfig.json new file mode 100644 index 00000000..cf561f95 --- /dev/null +++ b/src/Blazor/src/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compileOnSave": true, + "buildOptions": { + "emitEntryPoint": true, + "preserveCompilationContext": true, + "copyToOutput": { + "include": [ + "appsettings.json", + "appsettings.Development.json" + ] + } + }, + "compilerOptions": { + "outDir": "../wwwroot/" + } +} diff --git a/src/Blazor/wwwroot/JSInterop.js b/src/Blazor/wwwroot/JSInterop.js new file mode 100644 index 00000000..7a873bb7 --- /dev/null +++ b/src/Blazor/wwwroot/JSInterop.js @@ -0,0 +1,22 @@ +"use strict"; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +exports.__esModule = true; +exports.JSInterop = void 0; +var dotnet_js_interop_1 = require("@microsoft/dotnet-js-interop"); +exports.JSInterop = { + invokeDotNetMethod: function (method) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + return dotnet_js_interop_1.DotNet.invokeMethodAsync.apply(dotnet_js_interop_1.DotNet, __spreadArray(['BlazorApp', method], args, false)); + } +}; diff --git a/src/Blazor/wwwroot/background.png b/src/Blazor/wwwroot/background.png new file mode 100644 index 00000000..e15a3bde Binary files /dev/null and b/src/Blazor/wwwroot/background.png differ diff --git a/src/Blazor/wwwroot/exampleJsInterop.js b/src/Blazor/wwwroot/exampleJsInterop.js new file mode 100644 index 00000000..5294766c --- /dev/null +++ b/src/Blazor/wwwroot/exampleJsInterop.js @@ -0,0 +1,6 @@ +// This is a JavaScript module that is loaded on demand. It can export any number of +// functions, and may import other JavaScript modules if required. + +export function showPrompt(message) { + return prompt(message, 'Type anything here'); +} diff --git a/src/Configuration/Dgmjr.Configuration.Extensions.csproj b/src/Configuration/Dgmjr.Configuration.Extensions.csproj index f93df525..296dd571 100644 --- a/src/Configuration/Dgmjr.Configuration.Extensions.csproj +++ b/src/Configuration/Dgmjr.Configuration.Extensions.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/DownstreamApis/Dgmjr.Web.DownstreamApis.csproj b/src/DownstreamApis/Dgmjr.Web.DownstreamApis.csproj deleted file mode 100644 index 7ca2ec25..00000000 --- a/src/DownstreamApis/Dgmjr.Web.DownstreamApis.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - - 0eb63fc8-4d68-471c-bf25-ff7fbe57a33f - net6.0;net8.0 - Contains classes for simplifying working with distributed API condfiguration - - - - - - - - - - - - - - - - - - - diff --git a/src/DownstreamApis/Dgmjr.Web.DownstreamApis.props b/src/DownstreamApis/Dgmjr.Web.DownstreamApis.props deleted file mode 100644 index 42cb996a..00000000 --- a/src/DownstreamApis/Dgmjr.Web.DownstreamApis.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/DownstreamApis/Dgmjr.Web.DownstreamApis.sln b/src/DownstreamApis/Dgmjr.Web.DownstreamApis.sln deleted file mode 100644 index 25059298..00000000 --- a/src/DownstreamApis/Dgmjr.Web.DownstreamApis.sln +++ /dev/null @@ -1,56 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" - ProjectSection(SolutionItems) = preProject - ..\..\Directory.Build.props = ..\..\Directory.Build.props - ..\..\..\..\Directory.Build.targets = ..\..\..\..\Directory.Build.targets - ..\..\..\..\global.json = ..\..\..\..\global.json - ..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\Packages\Versions.Local.props - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Mime", "..\Http\Mime\Dgmjr.Mime.csproj", "{6F24CF7B-856B-4A33-BF3C-783A45117FFA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Web.DownstreamApis", "Dgmjr.Web.DownstreamApis.csproj", "{0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Local|Any CPU = Local|Any CPU - Debug|Any CPU = Debug|Any CPU - Testing|Any CPU = Testing|Any CPU - Staging|Any CPU = Staging|Any CPU - Production|Any CPU = Production|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Local|Any CPU.ActiveCfg = Local|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Local|Any CPU.Build.0 = Local|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Testing|Any CPU.Build.0 = Testing|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Staging|Any CPU.Build.0 = Staging|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Production|Any CPU.ActiveCfg = Local|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Production|Any CPU.Build.0 = Local|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6F24CF7B-856B-4A33-BF3C-783A45117FFA}.Release|Any CPU.Build.0 = Release|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Local|Any CPU.ActiveCfg = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Local|Any CPU.Build.0 = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Testing|Any CPU.Build.0 = Testing|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Staging|Any CPU.Build.0 = Staging|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Production|Any CPU.ActiveCfg = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Production|Any CPU.Build.0 = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {25BBCE17-E6E9-4227-8EF6-7C7C460053E1} - EndGlobalSection -EndGlobal diff --git a/src/DownstreamApis/DownstreamApiOptionsConfigurator.cs b/src/DownstreamApis/DownstreamApiOptionsConfigurator.cs deleted file mode 100644 index 2d2e8210..00000000 --- a/src/DownstreamApis/DownstreamApiOptionsConfigurator.cs +++ /dev/null @@ -1,28 +0,0 @@ -/* - * DownstreamApiOptionsConfigurator.cs - * - * Created: 2023-06-27T00:06:27-05:00 - * Modified: 2024-15-28T14:15:43-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Web.DownstreamApis; - -using Application = Dgmjr.Mime.Application; -using System.Net.Http; - -public class DownstreamApiOptionsConfigurator(IOptions jsonOptions) - : IConfigureOptions -{ - private readonly Jso _jso = jsonOptions?.Value?.JsonSerializerOptions; - - public void Configure(DownstreamApiOptions options) - { - options.Serializer = requestObject => - new StringContent(Serialize(requestObject, _jso), UTF8, Application.Json.DisplayName); - } -} diff --git a/src/DownstreamApis/DownstreamApiServiceCollectionExtensions.cs b/src/DownstreamApis/DownstreamApiServiceCollectionExtensions.cs deleted file mode 100644 index 9cf82086..00000000 --- a/src/DownstreamApis/DownstreamApiServiceCollectionExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -/* - * DownstreamApiServiceCollectionExtensions.cs - * - * Created: 2023-17-31T14:17:16-05:00 - * Modified: 2024-16-28T14:16:16-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Microsoft.Extensions.DependencyInjection; - -using Microsoft.Extensions.Configuration; - -public static class DownstreamApiServiceCollectionExtensions -{ - public static IServiceCollection ConfigureDownstreamApi( - this IServiceCollection services, - string name, - Action configureOptions - ) - { - services.Configure(name, configureOptions); - services.AddHttpClient(name); - services.AddSingleton< - IConfigureOptions, - DownstreamApiOptionsConfigurator - >(); - return services; - } - - public static IServiceCollection ConfigureDownstreamApi( - this IServiceCollection services, - string name, - IConfiguration configuration - ) - { - services.Configure(name, configuration); - services.AddHttpClient(name); - services.AddSingleton< - IConfigureOptions, - DownstreamApiOptionsConfigurator - >(); - return services; - } - - public static IServiceCollection ConfigureDownstreamApi( - this IServiceCollection services, - Action configureOptions - ) => services.ConfigureDownstreamApi(nameof(DownstreamApis), configureOptions); - - public static IServiceCollection ConfigureDownstreamApi( - this IServiceCollection services, - IConfiguration configuration - ) => services.ConfigureDownstreamApi(nameof(DownstreamApis), configuration); -} diff --git a/src/DownstreamApis/DownstreamApis.cs b/src/DownstreamApis/DownstreamApis.cs deleted file mode 100644 index 0d6ff40b..00000000 --- a/src/DownstreamApis/DownstreamApis.cs +++ /dev/null @@ -1,22 +0,0 @@ -/* - * DownstreamApis.cs - * - * Created: 2023-06-27T00:06:27-05:00 - * Modified: 2024-15-28T14:15:49-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Web.DownstreamApis; - -using System.Collections; - -public class DownstreamApis : Dictionary, IDownstreamApis -{ - public const string MicrosoftGraphOptions = "MicrosoftGraph"; - - MicrosoftGraphOptions IDownstreamApis.MicrosoftGraph { get; set; } -} diff --git a/src/DownstreamApis/DownstreamApisAutoConfigurator.cs b/src/DownstreamApis/DownstreamApisAutoConfigurator.cs deleted file mode 100644 index 93d8c44e..00000000 --- a/src/DownstreamApis/DownstreamApisAutoConfigurator.cs +++ /dev/null @@ -1,27 +0,0 @@ -/* - * DownstreamApisAutoConfigurator.cs - * - * Created: 2024-10-20T10:10:10-05:00 - * Modified: 2024-15-28T14:15:56-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Hosting; - -namespace Dgmjr.Web.DownstreamApis; - -public class DownstreamApisAutoConfigurator - : IConfigureIHostApplicationBuilder, - IConfigureIApplicationBuilder -{ - public ConfigurationOrder Order => ConfigurationOrder.AnyTime; - - public void Configure(WebApplicationBuilder builder) { } - - public void Configure(IApplicationBuilder app) { } -} diff --git a/src/DownstreamApis/DownstreamApisBase.cs b/src/DownstreamApis/DownstreamApisBase.cs deleted file mode 100644 index 69a24853..00000000 --- a/src/DownstreamApis/DownstreamApisBase.cs +++ /dev/null @@ -1,18 +0,0 @@ -/* - * DownstreamApisBase.cs - * - * Created: 2023-06-27T00:06:27-05:00 - * Modified: 2024-16-28T14:16:10-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Web.DownstreamApis; - -public abstract record class DownstreamApisBase -{ - public const string AppSettingsKey = nameof(DownstreamApis); -} diff --git a/src/DownstreamApis/IDownstreamApis.cs b/src/DownstreamApis/IDownstreamApis.cs deleted file mode 100644 index 96cf99ea..00000000 --- a/src/DownstreamApis/IDownstreamApis.cs +++ /dev/null @@ -1,21 +0,0 @@ -/* - * IDownstreamApis.cs - * - * Created: 2023-06-27T00:06:27-05:00 - * Modified: 2024-16-28T14:16:22-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Web.DownstreamApis; - -/// -/// Represents the interface for downstream APIs. -/// -public interface IDownstreamApis -{ - MicrosoftGraphOptions MicrosoftGraph { get; set; } -} diff --git a/src/DownstreamApis/JsonOptions.cs b/src/DownstreamApis/JsonOptions.cs deleted file mode 100644 index 3a6e098a..00000000 --- a/src/DownstreamApis/JsonOptions.cs +++ /dev/null @@ -1,28 +0,0 @@ -/* - * JsonOptions.cs - * - * Created: 2023-06-27T00:06:27-05:00 - * Modified: 2024-15-28T14:15:18-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -#if !NET5_0_OR_GREATER -namespace Microsoft.AspNetCore.Mvc; - -public class JsonOptions -{ - /// - /// Gets or sets a flag to determine whether error messages from JSON deserialization by the will be added to the . If false, a generic error message will be used instead. - /// - public bool AllowInputFormatterExceptionMessages { get; set; } - - /// - /// Gets the used by and . - /// - public Jso JsonSerializerOptions { get; } -} -#endif diff --git a/src/DownstreamApis/LICENSE.md b/src/DownstreamApis/LICENSE.md deleted file mode 100755 index 4f592f86..00000000 --- a/src/DownstreamApis/LICENSE.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -date: 2023-07-13T05:44:46:00-05:00Z -description: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files, yadda, yadda, yadda... -keywords: -- IP -- copyright -- license -- mit -permissions: -- commercial-use -- modifications -- distribution -- private-use -conditions: -- include-copyright -limitations: -- liability -- warranty -lastmod: 2024-01-0T00:39:00.0000+05:00Z -license: MIT -slug: mit-license -title: MIT License -type: license ---- - -# MIT License - -## Copyright © 2022-2024 [David G. Moore, Jr.](mailto:david@dgmjr.io "Send Dr. Moore") ([@dgmjr](https://github.com/dgmjr "Contact Dr. Moore on GitHub")), All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/src/DownstreamApis/README.md b/src/DownstreamApis/README.md deleted file mode 100644 index 001e5207..00000000 --- a/src/DownstreamApis/README.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: -lastmod: 2023-56-22T19:56:51.6475-05:00Z -date: 2023-56-22T19:56:51.6476-05:00Z -license: MIT -slug: Dgmjr.Web.DownstreamApis-readme -version: -authors: - - dgmjr; -description: Dgmjr.Web.DownstreamApis Readme #TODO: write description for Dgmjr.Web.DownstreamApis Readme -keywords: -- Dgmjr.Web.DownstreamApis - - dgmjr - - dgmjr-io -type: readme ---- -# Dgmjr.Web.DownstreamApis Readme - -## Package Description -## Getting Started -## Prerequisites -## Installation -## Usage -## Contributing -## Versioning -Built from [commit on branch main at ] -(/tree/) diff --git a/src/DownstreamApis/icon.png b/src/DownstreamApis/icon.png deleted file mode 100644 index db07a039..00000000 Binary files a/src/DownstreamApis/icon.png and /dev/null differ diff --git a/src/Http/CorrelationId b/src/Http/CorrelationId index 7b647e57..330b6389 160000 --- a/src/Http/CorrelationId +++ b/src/Http/CorrelationId @@ -1 +1 @@ -Subproject commit 7b647e57cf5e069290ff5b835c82b1157bbea1b3 +Subproject commit 330b638960c5fe4a4862c2197fcde19f62b1eaa5 diff --git a/src/Http/Mime/Enums/ImageMediaTypes.cs b/src/Http/Mime/Enums/ImageMediaTypes.cs index bf52c226..d3dedfe5 100644 --- a/src/Http/Mime/Enums/ImageMediaTypes.cs +++ b/src/Http/Mime/Enums/ImageMediaTypes.cs @@ -62,6 +62,7 @@ public enum ImageMediaTypes [Display(Name = ImageMediaTypeNames.Icon, Description = "Icon image")] [EnumMember(Value = ImageMediaTypeNames.Icon)] [Uri(IanaMediaTypeUrlBase + ImageMediaTypeNames.Icon)] + // [Synonyms([ImageMediaTypeNames.XIcon])] Icon, /// AVIF image diff --git a/src/Http/Mime/ImageMediaTypeNames.cs b/src/Http/Mime/ImageMediaTypeNames.cs index 1d99cdb1..6076d6c3 100644 --- a/src/Http/Mime/ImageMediaTypeNames.cs +++ b/src/Http/Mime/ImageMediaTypeNames.cs @@ -17,102 +17,106 @@ public static class ImageMediaTypeNames /// The base type for all image types. /// See IANA Media Types for more information. /// - /// image/ + /// image public const string Base = "image"; /// Media type for any image. - /// * + /// /* public const string Any = Base + "/*"; /// GIF image - /// gif + /// /gif public const string Gif = Base + "/gif"; /// JPEG image - /// jpeg + /// /jpeg public const string Jpeg = Base + "/jpeg"; /// PNG image - /// png + /// /png public const string Png = Base + "/png"; /// TIFF image - /// tiff + /// /tiff public const string Tiff = Base + "/tiff"; /// SVG image - /// svg+xml + /// /svg+xml public const string Svg = Base + "/svg+xml"; /// Icon image - /// vnd.microsoft.icon + /// /vnd.microsoft.icon public const string Icon = Base + "/vnd.microsoft.icon"; /// AVIF image - /// avif + /// /avif public const string Avif = Base + "/avif"; /// Bitmap image - /// bmp + /// /bmp public const string Bmp = Base + "/bmp"; /// WebP image - /// webp + /// /webp public const string Webp = Base + "/webp"; /// APNG image - /// apng + /// /apng public const string Apng = Base + "/apng"; /// HEIF image - /// heif + /// /heif public const string Heif = Base + "/heif"; /// HEIC image - /// heic + /// /heic public const string Heic = Base + "/heic"; /// HEIF sequence image - /// heif-sequence + /// /heif-sequence public const string HeifSequence = Base + "/heif-sequence"; /// HEIC sequence image - /// heic-sequence + /// /heic-sequence public const string HeicSequence = Base + "/heic-sequence"; /// JP2 image - /// jp2 + /// /jp2 public const string Jp2 = Base + "/jp2"; /// JPM image - /// jpm + /// /jpm public const string Jpm = Base + "/jpm"; /// JPX image - /// jpx + /// /jpx public const string Jpx = Base + "/jpx"; /// JB2 image - /// jb2 + /// /jb2 public const string Jb2 = Base + "/jb2"; /// SWF image - /// x-shockwave-flash + /// /x-shockwave-flash public const string Swf = Base + "/x-shockwave-flash"; /// FlashPix image - /// vnd.adobe.photoshop + /// /vnd.adobe.photoshop public const string FlashPix = Base + "/vnd.adobe.photoshop"; /// Camera image - /// x-canon-cr2 + /// /x-canon-cr2 public const string Camera = Base + "/x-canon-cr2"; /// Camera image - /// x-canon-crw + /// /x-canon-crw public const string Camera2 = Base + "/x-canon-crw"; /// Camera image - /// x-nikon-nef + /// /x-nikon-nef public const string Camera3 = Base + "/x-nikon-nef"; + + /// Synonym for .ico + /// /x-icon + public const string XIcon = Base + "/x-icon"; } diff --git a/src/MicrosoftGraph/.vscode/settings.json b/src/MicrosoftGraph/.vscode/settings.json deleted file mode 100644 index 40ac7cbc..00000000 --- a/src/MicrosoftGraph/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files.exclude": { - "**/.vs": false - } -} diff --git a/src/MicrosoftGraph/Abstractions/IApplicationService.cs b/src/MicrosoftGraph/Abstractions/IApplicationService.cs deleted file mode 100644 index 0afff115..00000000 --- a/src/MicrosoftGraph/Abstractions/IApplicationService.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Dgmjr.Graph.Abstractions; - -public interface IApplicationService : IMsGraphService -{ -} diff --git a/src/MicrosoftGraph/Abstractions/IDirectoryObjectsService.cs b/src/MicrosoftGraph/Abstractions/IDirectoryObjectsService.cs deleted file mode 100644 index 40d7bfa8..00000000 --- a/src/MicrosoftGraph/Abstractions/IDirectoryObjectsService.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Dgmjr.Graph.Abstractions; - -public interface IDirectoryObjectsService : IMsGraphService -{ - Task CreateAsync(DirectoryObject directoryObject, CancellationToken cancellationToken = default); - Task DeleteAsync(string id, CancellationToken cancellationToken = default); - Task GetAsync(string id, CancellationToken cancellationToken = default); - Task GetAsync(string id, string property, CancellationToken cancellationToken = default); - Task UpdateAsync(string id, DirectoryObject directoryObject, CancellationToken cancellationToken = default); -} diff --git a/src/MicrosoftGraph/Abstractions/IHaveAGraphClient.cs b/src/MicrosoftGraph/Abstractions/IHaveAGraphClient.cs deleted file mode 100644 index f5819017..00000000 --- a/src/MicrosoftGraph/Abstractions/IHaveAGraphClient.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Dgmjr.Graph.Abstractions; -public interface IHaveAGraphClient -{ - /// Retrieves the current instance of being used to service the request - public GraphServiceClient Graph { get; } -} diff --git a/src/MicrosoftGraph/Abstractions/IPassphraseGenerator.cs b/src/MicrosoftGraph/Abstractions/IPassphraseGenerator.cs deleted file mode 100644 index 7d5ad542..00000000 --- a/src/MicrosoftGraph/Abstractions/IPassphraseGenerator.cs +++ /dev/null @@ -1,18 +0,0 @@ -/* - * PasswordGenerator.cs - * - * Created: 2022-12-31-06:39:48 - * Modified: 2022-12-31-06:39:49 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2022-2023 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Identity; - -public interface IPassphraseGenerator -{ - string Generate(); -} diff --git a/src/MicrosoftGraph/Abstractions/IUsersService.cs b/src/MicrosoftGraph/Abstractions/IUsersService.cs deleted file mode 100644 index b1f8cc12..00000000 --- a/src/MicrosoftGraph/Abstractions/IUsersService.cs +++ /dev/null @@ -1,199 +0,0 @@ -namespace Dgmjr.Graph.Abstractions; - -using Microsoft.Extensions.Logging; -using Microsoft.Graph; - -public interface IUsersService : IMsGraphService -{ - /// - /// Assigns an app role to a user asynchronously. - /// - /// The ID of the user. - /// The ID of the app. - /// The ID of the app role. - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains the assigned app role. - Task AssignToAppRoleAsync( - string userId, - string appId, - string appRoleId, - CancellationToken cancellationToken = default - ); - - /// - /// Assigns an app role to a user asynchronously. - /// - /// The ID of the user. - /// The ID of the app. - /// The ID of the app role. - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains the assigned app role. - Task AssignToAppRoleAsync( - guid userId, - guid appId, - guid appRoleId, - CancellationToken cancellationToken = default - ); - - /// - /// Creates a user asynchronously. - /// - /// The user object to create. - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains the created user. - Task CreateAsync(User user, CancellationToken cancellationToken = default); - - /// - /// Deletes a user asynchronously based on their ID. - /// - /// The ID of the user to delete. - /// The cancellation token. - /// A task representing the asynchronous operation. - Task DeleteAsync(string id, CancellationToken cancellationToken = default); - - /// - /// Gets a user asynchronously based on their ID. - /// - /// The ID of the user to get. - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains the retrieved user. - Task GetAsync(string id, CancellationToken cancellationToken = default); - - /// - /// Gets a user asynchronously based on their ID and a specific property. - /// - /// The ID of the user to get. - /// The specific property to retrieve. - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains the retrieved user. - Task GetAsync(string id, string property, CancellationToken cancellationToken = default); - - /// - /// Gets extension properties asynchronously. - /// - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains an array of extension properties. - Task GetExtensionPropertiesAsync(CancellationToken cancellationToken = default); - - /// - /// Gets the currently logged-in user asynchronously. - /// - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains the current user. - Task GetMeAsync(CancellationToken cancellationToken = default); - - /// Gets the ID of the currently logged-in user asynchronously. - /// The cancellation token. - Task GetMyIdAsync(CancellationToken cancellationToken = default); - - /// - /// Finds a user by their sign-in name asynchronously. - /// - /// The sign-in name of the user. - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains the found user, or null if not found. - Task FindBySignInNameAsync(string name, CancellationToken cancellationToken = default); - - /// - /// Gets a list of users with a specific custom attribute. - /// - /// The GraphServiceClient instance. - /// The name of the custom attribute. - /// The cancellation token. - /// A task representing the asynchronous operation. The task result contains a list of users with the specified custom attribute. - Task> GetUsersWithCustomAttribute( - GraphServiceClient graphClient, - string attributeName, - CancellationToken cancellationToken = default - ); - - /// - /// Checks if a user is in an app role asynchronously. - /// - /// The ID of the user. - /// The ID of the app. - /// The ID of the app role. - /// The cancellation token. - /// A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the user is in the app role. - Task IsInAppRoleAsync( - string id, - string appId, - string appRoleId, - CancellationToken cancellationToken = default - ); - - /// - /// Sets the password for a user by user ID asynchronously. - /// - /// The ID of the user. - /// The new password for the user. - /// Optional. Specifies whether the user should be forced to change the password on the next sign-in. Default is false. - /// The cancellation token. - /// A task that represents the asynchronous operation. - Task SetPasswordByUserId( - string userId, - string password, - bool forceChangePasswordNextSignIn = false, - CancellationToken cancellationToken = default - ); - - /// - /// Unassigns an app role from a user asynchronously. - /// - /// The ID of the user. - /// The ID of the app. - /// The ID of the app role. - /// The cancellation token. - /// A task that represents the asynchronous operation. - Task UnassignAppRoleAsync( - string userId, - string appId, - string appRoleId, - CancellationToken cancellationToken = default - ); - - /// - /// Unassigns an app role from a user asynchronously. - /// - /// The ID of the user. - /// The ID of the app. - /// The ID of the app role. - /// The cancellation token. - /// A task that represents the asynchronous operation. - Task UnassignAppRoleAsync( - guid userId, - guid appId, - guid appRoleId, - CancellationToken cancellationToken = default - ); - - /// Updates a user property asynchronously. - /// The ID of the user to update. - /// The name of the property to update. - /// The new value for the property. - /// The cancellation token. - Task UpdateAsync(guid id, string property, string value, CancellationToken cancellationToken = default); - - /// - /// Updates a user asynchronously. - /// - /// The updated user object. - /// The cancellation token. - /// A task that represents the asynchronous operation. The task result contains the updated user object. - Task UpdateAsync(User user, CancellationToken cancellationToken = default); - - /// - /// Updates a user property asynchronously. - /// - /// The ID of the user to update. - /// The name of the property to update. - /// The new value for the property. - /// The cancellation token. - /// A task that represents the asynchronous operation. The task result contains the updated user object. - Task UpdateAsync( - string id, - string property, - string value, - CancellationToken cancellationToken = default - ); -} diff --git a/src/MicrosoftGraph/Configuration/MicrosoftGraphAutoConfigurator.cs b/src/MicrosoftGraph/Configuration/MicrosoftGraphAutoConfigurator.cs deleted file mode 100644 index 2b7916fe..00000000 --- a/src/MicrosoftGraph/Configuration/MicrosoftGraphAutoConfigurator.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Microsoft.Extensions.DependencyInjection; - -public class MicrosoftGraphAutoConfigurator : IConfigureIHostApplicationBuilder -{ - public ConfigurationOrder Order => ConfigurationOrder.AnyTime; - - public void Configure(WebApplicationBuilder builder) - { - builder.Services.AddMicrosoftGraph(builder.Configuration); - } -} diff --git a/src/MicrosoftGraph/Configuration/UserAppRolesConfigurator.cs b/src/MicrosoftGraph/Configuration/UserAppRolesConfigurator.cs deleted file mode 100644 index f482f0b9..00000000 --- a/src/MicrosoftGraph/Configuration/UserAppRolesConfigurator.cs +++ /dev/null @@ -1,95 +0,0 @@ -namespace Dgmjr.Graph.Configuration; - -using System; -using System.Security.Claims; -using System.Security.Extensions; - -using Dgmjr.Graph.TokenProviders; - -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Kiota.Abstractions.Authentication; - -public class UserAppRolesConfigurator(ILogger logger, IHttpContextAccessor httpContextAccessor) : IConfigureOptions, ILog -{ - public ILogger Logger => logger; - private HttpContext HttpContext => httpContextAccessor.HttpContext!; - private IServiceProvider Services => HttpContext.RequestServices; - - public void Configure(MicrosoftIdentityOptions options) - { - options.Events.OnTokenValidated += OnTokenValidated; - options.Events.OnAuthenticationFailed += OnAuthenticationFailed; - options.Events.OnAuthorizationCodeReceived += OnAuthorizationCodeReceived; - options.Events.OnMessageReceived += OnMessageReceived; - options.Events.OnRedirectToIdentityProvider += OnRedirectToIdentityProvider; - options.Events.OnRemoteFailure += OnRemoteFailure; - } - - private async Task OnRemoteFailure(RemoteFailureContext context) - { - Logger.RemoteFailure(context.Failure); - } - - private async Task OnRedirectToIdentityProvider(RedirectContext context) - { - Logger.RedirectToIdentityProvider(context.ProtocolMessage); - } - - private async Task OnMessageReceived(MessageReceivedContext context) - { - Logger.MessageReceived(context.ProtocolMessage); - } - - private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context) - { - Logger.AuthorizationCodeReceived(context.TokenEndpointResponse); - } - - private async Task OnAuthenticationFailed(AuthenticationFailedContext context) - { - Logger.AuthenticationFailed(context.Exception); - } - - private static async Task OnTokenValidated(TokenValidatedContext context) - { - using var scope = context.HttpContext.RequestServices.CreateScope(); - using var activity = Dgmjr.Graph.Telemetry.Activities.TokenAcquisitionActivitySource.StartActivity( - nameof(OnTokenValidated), - ActivityKind.Client - ); - var logger = scope.ServiceProvider.GetRequiredService>(); - logger.BeginningSupplementaryTokenAcquisitionAndCreation(context.Principal); - activity.AddTag("UserObjectId", context.Principal.GetObjectId()); - activity.AddTag("UserTenantId", context.Principal.GetTenantId()); - - var services = scope.ServiceProvider; - var tokenAcquisition = services.GetRequiredService(); - var graphClientOptions = services.GetRequiredService>().Value; - - var graphClient = new GraphServiceClient( - (Microsoft.Graph.IAuthenticationProvider)(new BaseBearerTokenAuthenticationProvider( - new TokenAcquisitionTokenProvider( - tokenAcquisition, - [MsGraphScopes.Default], - context.Principal - ) - ) as IAuthenticationProvider) - ); - var me = await graphClient.Me.Request().GetAsync(); - var app = await graphClient.Applications[graphClientOptions.AzureAdB2CExtensionsApplicationId.ToString()].Request().GetAsync(); - var appRoles = app.AppRoles; - var myAppRoles = me.AppRoleAssignments.Where(x => x.ResourceId == graphClientOptions.AzureAdB2CExtensionsApplicationId).ToList(); - var claims = new List(); - foreach (var appRole in myAppRoles) - { - var theAppRole = appRoles.FirstOrDefault(x => x.Id.ToString() == appRole.Id); - if(theAppRole != null) - { - claims.Add(new(ClaimTypes.Role, theAppRole.Value)); - } - } - logger.SupplementaryTokenAcquisitionAndCreationComplete(context.Principal); - } -} diff --git a/src/MicrosoftGraph/Constants/CacheKeys.cs b/src/MicrosoftGraph/Constants/CacheKeys.cs deleted file mode 100644 index b6a635c9..00000000 --- a/src/MicrosoftGraph/Constants/CacheKeys.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Dgmjr.Graph.Constants; - -public static class CacheKeys -{ - public const string ExtensionProperties = $"{MsGraph}:ExtensionProperties"; -} diff --git a/src/MicrosoftGraph/Constants/MimeTypes.cs b/src/MicrosoftGraph/Constants/MimeTypes.cs deleted file mode 100644 index 6fe5d1ca..00000000 --- a/src/MicrosoftGraph/Constants/MimeTypes.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace Dgmjr.Graph.Constants; - -using Dgmjr.Mime; -using Application = Dgmjr.Mime.Application; - -public static class MimeTypes -{ - /// msgraph - private const string MsGraph = "msgraph"; - - /// -extension-properties - public const string MsGraphExtensionPropertiesList = $"{MsGraph}-extension-properties"; - - /// / - public const string MsGraphExtensionPropertiesListJson = - $"{Application.Base.DisplayName}/{MsGraphExtensionPropertiesList}{Suffixes.Json.DisplayName}"; - - /// / - public const string MsGraphExtensionPropertiesListXml = - $"{Application.Base.DisplayName}/{MsGraphExtensionPropertiesList}{Suffixes.Xml.DisplayName}"; - - /// / - public const string MsGraphExtensionPropertiesListBson = - $"{Application.Base.DisplayName}/{MsGraphExtensionPropertiesList}{Suffixes.Bson.DisplayName}"; - - /// / - public const string MsGraphExtensionPropertiesListMsgPack = - $"{Application.Base.DisplayName}/{MsGraphExtensionPropertiesList}{Suffixes.MessagePack.DisplayName}"; - - /// -user - public const string MsGraphUser = $"{MsGraph}-user"; - - /// / - public const string MsGraphUserJson = - $"{Application.Base.DisplayName}/{MsGraphUser}{Suffixes.Json.DisplayName}"; - - /// / - public const string MsGraphUserXml = - $"{Application.Base.DisplayName}/{MsGraphUser}{Suffixes.Xml.DisplayName}"; - - /// / - public const string MsGraphUserBson = - $"{Application.Base.DisplayName}/{MsGraphUser}{Suffixes.Bson.DisplayName}"; - - /// / - public const string MsGraphUserMsgPack = - $"{Application.Base.DisplayName}/{MsGraphUser}{Suffixes.MessagePack.DisplayName}"; -} diff --git a/src/MicrosoftGraph/Constants/MsGraphConstants.cs b/src/MicrosoftGraph/Constants/MsGraphConstants.cs deleted file mode 100644 index 205ab78e..00000000 --- a/src/MicrosoftGraph/Constants/MsGraphConstants.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Dgmjr.Graph; - -using Dgmjr.Web.DownstreamApis; - -public static class MsGraphConstants -{ - public const string Scopes = nameof(Scopes); - public const string MicrosoftGraph = "MicrosoftGraph"; - - public const string MicrosoftGraph_ClientId = "ClientId"; - - public const string MicrosoftGraph_ClientSecret = "ClientSecret"; - - public const string DownstreamApis_MicrosoftGraph = - $"{DownstreamApisBase.AppSettingsKey}:{MicrosoftGraph}"; - public const string DownstreamApis_MicrosoftGraph_Scopes = - $"{DownstreamApisBase.AppSettingsKey}:{MicrosoftGraph}:{Scopes}"; - - public const string AzureAdB2CExtensionsApplicationId = nameof( - AzureAdB2CExtensionsApplicationId - ); - - public const string DownstreamApis_MicrosoftGraph_AzureAdB2CExtensionsApplicationId = - $"{DownstreamApis_MicrosoftGraph}:{AzureAdB2CExtensionsApplicationId}"; - - public static readonly string[] ValidMsGraphHosts = - [ - "graph.microsoft.com", - "graph.microsoft.us", - "dod-graph.microsoft.us", - "graph.microsoft.de", - "microsoftgraph.chinacloudapi.cn" - ]; -} diff --git a/src/MicrosoftGraph/Constants/ODataUris.cs b/src/MicrosoftGraph/Constants/ODataUris.cs deleted file mode 100644 index 0f2960eb..00000000 --- a/src/MicrosoftGraph/Constants/ODataUris.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Dgmjr.Graph.Constants; - -public static class ODataUris -{ - /// https://graph.microsoft.com/v1.0/$metadata#Collection(extensionProperty) - public const string ExtensionPropertyODataContextString = "https://graph.microsoft.com/v1.0/$metadata#Collection(extensionProperty)"; - - /// #microsoft.graph.extensionProperty - public const string ExtensionPropertyODataTypeString = "#microsoft.graph.extensionProperty"; -} diff --git a/src/MicrosoftGraph/Constants/Scopes.cs b/src/MicrosoftGraph/Constants/Scopes.cs deleted file mode 100644 index f0d04ae2..00000000 --- a/src/MicrosoftGraph/Constants/Scopes.cs +++ /dev/null @@ -1,80 +0,0 @@ -namespace Dgmjr.Graph.Constants; - -public class MsGraphScopes -{ - /// https://graph.microsoft.com/ - public const string Base = "https://graph.microsoft.com/"; - - /// .default - public const string Default = Base + ".default"; - - public static class User - { - /// User. - private const string Base = MsGraphScopes.Base + "User."; - - public static class Read - { - /// Read - public const string Base = User.Base + "Read"; - - /// .All - public const string All = Base + ".All"; - /// Basic.All - public const string BasicAll = Base + "Basic.All"; - } - - public static class ReadWrite - { - /// ReadWrite - public const string Base = User.Base + "ReadWrite"; - - /// .All - public const string All = Base + ".All"; - } - - public static class Invite - { - /// Invite - private const string Base = User.Base + "Invite."; - /// .All - public const string All = Base + ".All"; - } - - public static class ManageIdentities - { - /// ManageIdentities - private const string Base = User.Base + "ManageIdentities."; - /// .All - public const string All = Base + ".All"; - } - - public static class Export - { - /// Export - private const string Base = User.Base + "Export."; - /// .All - public const string All = Base + ".All"; - } - - public static class EnableDisableAccount - { - /// EnableDisableAccount - private const string Base = User.Base + "EnableDisableAccount."; - /// .All - public const string All = Base + ".All"; - } - } - - public static class Directory - { - public const string Base = MsGraphScopes.Base + "Directory."; - - public static class Read - { - public const string Base = Directory.Base + "Read"; - - public const string All = Base + ".All"; - } - } -} diff --git a/src/MicrosoftGraph/Constants/Uris.cs b/src/MicrosoftGraph/Constants/Uris.cs deleted file mode 100644 index 1ad41cbe..00000000 --- a/src/MicrosoftGraph/Constants/Uris.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Dgmjr.Graph.Constants; - -using Dgmjr.Mime; - -public static class Uris -{ - public const string Api = "/api"; - public const string MsGraph = "/msgraph"; - public const string Users = "/users"; - public const string MsGraphApi = $"{Api}{MsGraph}"; - public const string Me = "/me"; - public const string DirectoryObjects = "/directoryObjects"; - public const string ExtensionProperties = "extensionProperties"; -} diff --git a/src/MicrosoftGraph/Controllers/DirectoryObjectsController.cs b/src/MicrosoftGraph/Controllers/DirectoryObjectsController.cs deleted file mode 100644 index 68622dee..00000000 --- a/src/MicrosoftGraph/Controllers/DirectoryObjectsController.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* - * DirectoryObjectsController.cs - * - * Created: 2024-55-16T14:55:21-05:00 - * Modified: 2024-55-16T14:55:21-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Graph.Controllers; - -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; - -[Route($"{MsGraphApi}{DirectoryObjects}")] -[AuthorizeForScopes(Scopes = [MsGraphScopes.Directory.Read.All])] -public class DirectoryObjectsController( - ILogger logger, - IServiceProvider services -) : MsGraphController(logger, services) -{ - private IDirectoryObjectsService DirectoryObjectsService => - services.GetRequiredService(); - - [HttpGet(Uris.ExtensionProperties)] - public async Task GetExtensionPropertiesAsync() - { - Logger.Get(Request.Path); - return Ok( - ( - await DirectoryObjectsService.GetExtensionPropertiesAsync(default) - ).Cast() - ); - } -} diff --git a/src/MicrosoftGraph/Controllers/MeController.cs b/src/MicrosoftGraph/Controllers/MeController.cs deleted file mode 100644 index 5f3bb052..00000000 --- a/src/MicrosoftGraph/Controllers/MeController.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace Dgmjr.Graph.Controllers; -using Dgmjr.Graph.Abstractions; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; -using Application = Dgmjr.Mime.Application; -using Dgmjr.Abstractions; -using Microsoft.Extensions.Logging; -using Microsoft.Identity.Web.Resource; -using User = Microsoft.Graph.User; - -[AuthorizeForScopes(Scopes = [MsGraphScopes.User.Read.Base])] -[RequiredScope([MsGraphScopes.User.Read.Base])] -[Route($"{MsGraphApi}{Me}")] -public class MeController(ILogger logger, IServiceProvider services) : MsGraphController(logger, services) -{ - private readonly IUsersService _users = services.GetRequiredService(); - - [HttpGet] - [ProducesResponseType(typeof(User), Status200OK)] - [Produces(MsGraphUserJson, MsGraphUserXml, MsGraphUserBson, MsGraphUserMsgPack)] - public async Task Get() - { - Logger.Get(Me); - return Ok(await _users.GetMeAsync()); - } - - [HttpGet("{property}")] - [Produces(Text.Plain.DisplayName, Application.Json.DisplayName, Application.Xml.DisplayName, Application.Bson.DisplayName, Application.MessagePack.DisplayName)] - [ProducesResponseType(typeof(string), Status200OK)] - [ProducesResponseType(typeof(int), Status200OK)] - [ProducesResponseType(typeof(long), Status200OK)] - public async Task Get([FromRoute] string property) - { - Logger.Get(Request.Path); - var propertyFullName = new DGraphExtensionProperty(property).Name; - var result = await Graph.Me.Request().Select(u => u.AdditionalData[propertyFullName]).GetAsync(); - var value = result.AdditionalData[new DGraphExtensionProperty(property).Name]; - return Ok(value); - } - - [HttpPost("{property}")] - [Produces(MsGraphUserJson, MsGraphUserXml, MsGraphUserBson, MsGraphUserMsgPack)] - public async Task Post([FromRoute] string property, [FromQuery] string value) - { - Logger.Post(Request.Path); - var me = await Graph.Me.Request().GetAsync(); - me.AdditionalData[property] = value; - return Ok(await Graph.Me.Request().UpdateAsync(me)); - } - - [HttpGet(Uris.ExtensionProperties)] - [ProducesResponseType(typeof(DGraphExtensionProperty[]), Status200OK)] - [Produces(MsGraphExtensionPropertiesListJson, MsGraphExtensionPropertiesListXml, MsGraphExtensionPropertiesListBson, MsGraphExtensionPropertiesListMsgPack)] - public async Task GetExtensionProperties() - { - Logger.Get($"{Me}/{Uris.ExtensionProperties}"); - return Ok((await _users.GetExtensionPropertiesAsync(default)).Cast()); - } -} diff --git a/src/MicrosoftGraph/Controllers/MsGraphController.cs b/src/MicrosoftGraph/Controllers/MsGraphController.cs deleted file mode 100644 index 375ce749..00000000 --- a/src/MicrosoftGraph/Controllers/MsGraphController.cs +++ /dev/null @@ -1,25 +0,0 @@ -/* - * MsGraphController.cs - * - * Created: 2024-55-16T14:55:53-05:00 - * Modified: 2024-55-16T14:55:54-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Graph.Controllers; - -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; - -[Route(MsGraphApi)] -public abstract class MsGraphController(ILogger logger, IServiceProvider services) - : ControllerBase, - IHaveAGraphClient -{ - public ILogger Logger => logger; - public GraphServiceClient Graph => services.GetRequiredService(); -} diff --git a/src/MicrosoftGraph/Controllers/UsersController.cs b/src/MicrosoftGraph/Controllers/UsersController.cs deleted file mode 100644 index e5b351cd..00000000 --- a/src/MicrosoftGraph/Controllers/UsersController.cs +++ /dev/null @@ -1,73 +0,0 @@ -namespace Dgmjr.Graph.Controllers; - -using Dgmjr.Graph.Abstractions; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; -using Application = Dgmjr.Mime.Application; -using Dgmjr.Abstractions; -using User = Microsoft.Graph.User; - -[AuthorizeForScopes(ScopeKeySection = DownstreamApis_MicrosoftGraph_Scopes)] -[Route($"{MsGraphApi}{Users}")] -public class UsersController(ILogger logger, IServiceProvider services) - : MsGraphController(logger, services) -{ - private readonly IUsersService _users = services.GetRequiredService(); - - [HttpGet("{userId:guid}")] - [ProducesResponseType(typeof(User), Status200OK)] - [Produces(MsGraphUserJson, MsGraphUserXml, MsGraphUserBson, MsGraphUserMsgPack)] - public async Task Get([FromRoute] guid userId) - { - Logger.Get(Request.Path); - return Ok(await _users.GetAsync(userId.ToString())); - } - - [HttpGet("{property}")] - [Produces( - Text.Plain.DisplayName, - Application.Json.DisplayName, - Application.Xml.DisplayName, - Application.Bson.DisplayName, - Application.MessagePack.DisplayName - )] - [ProducesResponseType(typeof(string), Status200OK)] - [ProducesResponseType(typeof(int), Status200OK)] - [ProducesResponseType(typeof(long), Status200OK)] - public async Task Get([FromRoute] string property) - { - Logger.Get(Request.Path); - var result = await _users.GetAsync((await _users.GetMyIdAsync()).ToString(), property); - var value = result.AdditionalData[new DGraphExtensionProperty(property).Name]; - return Ok(value); - } - - [HttpPost("{userId}/{property}")] - [Produces(MsGraphUserJson, MsGraphUserXml, MsGraphUserBson, MsGraphUserMsgPack)] - public async Task Post( - [FromRoute] guid userId, - [FromRoute] string property, - [FromQuery] string value - ) - { - Logger.Post(Request.Path); - var user = await _users.UpdateAsync(userId.ToString(), property, value); - return Ok(user); - } - - [HttpGet(Uris.ExtensionProperties)] - [ProducesResponseType(typeof(DGraphExtensionProperty[]), Status200OK)] - [Produces( - MsGraphExtensionPropertiesListJson, - MsGraphExtensionPropertiesListXml, - MsGraphExtensionPropertiesListBson, - MsGraphExtensionPropertiesListMsgPack - )] - public async Task GetExtensionProperties() - { - Logger.Get(Request.Path); - return Ok( - (await _users.GetExtensionPropertiesAsync(default)).Cast() - ); - } -} diff --git a/src/MicrosoftGraph/Dgmjr.Graph.csproj b/src/MicrosoftGraph/Dgmjr.Graph.csproj deleted file mode 100644 index 694dca57..00000000 --- a/src/MicrosoftGraph/Dgmjr.Graph.csproj +++ /dev/null @@ -1,54 +0,0 @@ - - - net6.0;net8.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/MicrosoftGraph/Dgmjr.Graph.props b/src/MicrosoftGraph/Dgmjr.Graph.props deleted file mode 100644 index e67d6714..00000000 --- a/src/MicrosoftGraph/Dgmjr.Graph.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/MicrosoftGraph/Dgmjr.Graph.sln b/src/MicrosoftGraph/Dgmjr.Graph.sln deleted file mode 100644 index c0a8eeec..00000000 --- a/src/MicrosoftGraph/Dgmjr.Graph.sln +++ /dev/null @@ -1,56 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" - ProjectSection(SolutionItems) = preProject - ..\..\Directory.Build.props = ..\..\Directory.Build.props - ..\..\..\..\Directory.Build.targets = ..\..\..\..\Directory.Build.targets - ..\..\..\..\global.json = ..\..\..\..\global.json - ..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\Packages\Versions.Local.props - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Web.DownstreamApis", "..\DownstreamApis\Dgmjr.Web.DownstreamApis.csproj", "{0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Graph", "Dgmjr.Graph.csproj", "{04A895B2-EFA5-4512-92EA-A28B0917C7E2}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Local|Any CPU = Local|Any CPU - Debug|Any CPU = Debug|Any CPU - Testing|Any CPU = Testing|Any CPU - Staging|Any CPU = Staging|Any CPU - Production|Any CPU = Production|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Local|Any CPU.ActiveCfg = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Local|Any CPU.Build.0 = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Testing|Any CPU.Build.0 = Testing|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Staging|Any CPU.Build.0 = Staging|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Production|Any CPU.ActiveCfg = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Production|Any CPU.Build.0 = Local|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0EB63FC8-4D68-471C-BF25-FF7FBE57A33F}.Release|Any CPU.Build.0 = Release|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Local|Any CPU.ActiveCfg = Local|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Local|Any CPU.Build.0 = Local|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Testing|Any CPU.Build.0 = Testing|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Staging|Any CPU.Build.0 = Staging|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Production|Any CPU.ActiveCfg = Local|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Production|Any CPU.Build.0 = Local|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {04A895B2-EFA5-4512-92EA-A28B0917C7E2}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {5AF03949-454C-4A5D-A473-76EB9E230E98} - EndGlobalSection -EndGlobal diff --git a/src/MicrosoftGraph/Extensions/LoggingExtensions.cs b/src/MicrosoftGraph/Extensions/LoggingExtensions.cs deleted file mode 100644 index 2ea2bf75..00000000 --- a/src/MicrosoftGraph/Extensions/LoggingExtensions.cs +++ /dev/null @@ -1,106 +0,0 @@ -namespace Dgmjr.Graph; -using System.Security.Claims; -using Microsoft.IdentityModel.Protocols.OpenIdConnect; - -using ClaimsPrincipal = System.Security.Claims.ClaimsPrincipal; - -internal static partial class LoggingExtensions -{ - [LoggerMessage( - EventId = 1, - Level = LogLevel.Information, - Message = "Beginning supplementary token acquisition and creation for user {User}", - EventName = nameof(BeginningSupplementaryTokenAcquisitionAndCreation) - )] - public static partial void BeginningSupplementaryTokenAcquisitionAndCreation( - this ILogger logger, - ClaimsPrincipal user - ); - - [LoggerMessage( - EventId = 2, - Level = LogLevel.Information, - Message = "Supplementary token acquisition and creation for user {User} completed", - EventName = nameof(SupplementaryTokenAcquisitionAndCreationComplete) - )] - public static partial void SupplementaryTokenAcquisitionAndCreationComplete( - this ILogger logger, - ClaimsPrincipal user - ); - - [LoggerMessage( - EventId = 3, - Level = LogLevel.Information, - Message = "Authentication failed: {Exception}", - EventName = nameof(AuthenticationFailed) - )] - public static partial void AuthenticationFailed( - this ILogger logger, - Exception exception - ); - - [LoggerMessage( - EventId = 4, - Level = LogLevel.Information, - Message = "Authorization code received: {TokenEndpointResponse}", - EventName = nameof(AuthorizationCodeReceived) - )] - public static partial void AuthorizationCodeReceived( - this ILogger logger, - OpenIdConnectMessage tokenEndpointResponse - ); - - [LoggerMessage( - EventId = 5, - Level = LogLevel.Information, - Message = "Message received: {ProtocolMessage}", - EventName = nameof(MessageReceived) - )] - public static partial void MessageReceived( - this ILogger logger, - OpenIdConnectMessage protocolMessage - ); - - [LoggerMessage( - EventId = 6, - Level = LogLevel.Information, - Message = "Redirect to identity provider: {ProtocolMessage}", - EventName = nameof(RedirectToIdentityProvider) - )] - public static partial void RedirectToIdentityProvider( - this ILogger logger, - OpenIdConnectMessage protocolMessage - ); - - [LoggerMessage( - EventId = 7, - Level = LogLevel.Information, - Message = "Remote failure: {Failure}", - EventName = nameof(RemoteFailure) - )] - public static partial void RemoteFailure( - this ILogger logger, - Exception? failure - ); - - - // [LoggerMessage( - // EventId = 1, - // Level = LogLevel.Information, - // Message = "{Method} {Path}", - // EventName = nameof(PageVisited) - // )] - // public static partial void PageVisited( - // this ILogger logger, - // System.Net.Http.HttpMethod method, - // string path - // ); - - // [LoggerMessage( - // EventId = 1, - // Level = LogLevel.Information, - // Message = "{Method} {Path}", - // EventName = nameof(PageVisited) - // )] - // public static partial void PageVisited(this ILogger logger, string method, string path); -} diff --git a/src/MicrosoftGraph/Extensions/MicrosoftGraphServiceCollectionExtensions.cs b/src/MicrosoftGraph/Extensions/MicrosoftGraphServiceCollectionExtensions.cs deleted file mode 100644 index 478fd674..00000000 --- a/src/MicrosoftGraph/Extensions/MicrosoftGraphServiceCollectionExtensions.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Security.Claims; - -using Microsoft.Kiota.Abstractions.Authentication; -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Dgmjr.Graph.TokenProviders; -using IAuthenticationProvider = Microsoft.Graph.IAuthenticationProvider; -using Microsoft.ApplicationInsights; -using Dgmjr.Graph.Configuration; - -namespace Microsoft.Extensions.DependencyInjection; - -public static class MicrosoftGraphServiceCollectionExtensions -{ - public static IServiceCollection AddMicrosoftGraph( - this IServiceCollection services, - IConfiguration config - ) - { - var configSection = config.GetSection(DownstreamApis_MicrosoftGraph); - var options = configSection.Get(); - services - .AddMicrosoftGraph(options => config.Bind(options)) - .AddMicrosoftIdentityConsentHandler() - .ConfigureDownstreamApi(MicrosoftGraph, configSection); - services.AddScoped(); - services.AddScoped(); - services.Configure(configSection); - services.AddScoped(); - services.AddPassphraseGenerator(config); - services.AddSingleton, UserAppRolesConfigurator>(); - return services; - } - - public static IServiceCollection AddPassphraseGenerator( - this IServiceCollection services, - IConfiguration config - ) - { - services.Configure( - config.GetSection(PassphraseGeneratorOptions.AppSettingsKey) - ); - services.AddSingleton(); - return services; - } -} diff --git a/src/MicrosoftGraph/LICENSE.md b/src/MicrosoftGraph/LICENSE.md deleted file mode 100755 index 4f592f86..00000000 --- a/src/MicrosoftGraph/LICENSE.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -date: 2023-07-13T05:44:46:00-05:00Z -description: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files, yadda, yadda, yadda... -keywords: -- IP -- copyright -- license -- mit -permissions: -- commercial-use -- modifications -- distribution -- private-use -conditions: -- include-copyright -limitations: -- liability -- warranty -lastmod: 2024-01-0T00:39:00.0000+05:00Z -license: MIT -slug: mit-license -title: MIT License -type: license ---- - -# MIT License - -## Copyright © 2022-2024 [David G. Moore, Jr.](mailto:david@dgmjr.io "Send Dr. Moore") ([@dgmjr](https://github.com/dgmjr "Contact Dr. Moore on GitHub")), All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/src/MicrosoftGraph/Models/ExtensionProperty.cs b/src/MicrosoftGraph/Models/ExtensionProperty.cs deleted file mode 100644 index 31ce8f1d..00000000 --- a/src/MicrosoftGraph/Models/ExtensionProperty.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Dgmjr.Graph.Models; -using System.Runtime.InteropServices; - -[StructLayout(LayoutKind.Auto, Pack = 1)] -public partial record struct ExtensionProperty -{ - /// - [JProp("@odata.type")] - public Uri OdataContext { get; init; } = new(ODataUris.ExtensionPropertyODataTypeString); - - /// The name of the extension property - [JProp("id")] - public guid Id { get; init; } - - /// The data type of the extension property - [JProp("dataType")] - public ExtensionPropertyDataType DataType { get; init; } - - /// The description of the extension property - [JProp("description")] - public string Description { get; init; } - - /// The target object type of the extension property - [JProp("targetObjects")] - public TargetObjectType[] TargetObjects { get; init; } - - [JProp("isSyncedFromOnPremises")] - public bool IsSyncedFromOnPremises { get; init; } -} diff --git a/src/MicrosoftGraph/Models/ExtensionPropertyCreateDto.cs b/src/MicrosoftGraph/Models/ExtensionPropertyCreateDto.cs deleted file mode 100644 index a9bdd486..00000000 --- a/src/MicrosoftGraph/Models/ExtensionPropertyCreateDto.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Dgmjr.Graph.Models; - -public record struct ExtensionPropertyCreateDto -{ - /// The name of the extension property - [Required, JProp("name")] - public string Name { get; set; } - - /// The data type of the extension property - [Required, JProp("dataType")] - public ExtensionPropertyDataType DataType { get; set; } - - /// The description of the extension property - [JProp("description")] - public string Description { get; set; } - - /// The target object type of the extension property - [Required] - public TargetObjectType[] TargetObjects { get; set; } - - /// The name of the owner of the extension property - public string Owner { get; set; } - - /// The name of the owner of the extension property - public guid AppId { get; set; } - - /// The name of the owner of the extension property - public string Id { get; set; } -} diff --git a/src/MicrosoftGraph/Models/ExtensionPropertyDataType.cs b/src/MicrosoftGraph/Models/ExtensionPropertyDataType.cs deleted file mode 100644 index c18ef7f7..00000000 --- a/src/MicrosoftGraph/Models/ExtensionPropertyDataType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Dgmjr.Graph; - -public enum ExtensionPropertyDataType -{ - /// a 256-max array - Binary, - /// a 64-bit integral number - LargeInteger, - /// a 32-bit integral number - Integer, - /// a 256-max-char - String, - /// a or value - Boolean -} diff --git a/src/MicrosoftGraph/Models/ExtensionPropertyKey.cs b/src/MicrosoftGraph/Models/ExtensionPropertyKey.cs deleted file mode 100644 index d7be1031..00000000 --- a/src/MicrosoftGraph/Models/ExtensionPropertyKey.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace Dgmjr.Graph.Models; -using System.Text.RegularExpressions; - -[RegexDto(@"^extension_(?[a-fA-F0-9]{32})_(?\w+)$", BaseType: typeof(MgExtensionProperty), RegexOptions: _RegexOptions)] -public readonly partial record struct ExtensionProperty -{ - public ExtensionProperty(string extensionPropertyName, guid extensionsAppId) : this() - { - PropertyName = extensionPropertyName; - AppId = extensionsAppId; - } - - public const Rxo _RegexOptions = Rxo.Compiled | Rxo.IgnoreCase | Rxo.Singleline | Rxo.IgnorePatternWhitespace | Rxo.ExplicitCapture | Rxo.CultureInvariant; - - public const string FormatString = "extension_{0}_{1}"; - - public const string ExampleString = "extension_8c21ed0668e74eed94ecd1eabd572d98_example_property_name"; - - public const string EmptyString = "extension_00000000000000000000000000000000_empty"; - - public const string DescriptionString = $"An extension property key in the format of {ExampleString} for the {nameof(ExtensionProperty)} model."; - - public const string UriFormatString = "https://graph.microsoft.com/v1.0/applications/{0}/extensionProperties/{1}"; - - public static DGraphExtensionProperty Empty => new(EmptyString, guid.Empty); - - public string Name => Format(FormatString, AppId, PropertyName); - - public string Value => IsEmpty ? string.Empty : Name; - - public bool IsEmpty => Name == EmptyString; - - public DGraphExtensionProperty ExampleValue => new(ExampleString); - - public Uri Uri => new(Format(UriFormatString, AppId, PropertyName), Absolute); - - public int CompareTo(DGraphExtensionProperty other) => Value.CompareTo(other.Value); - - public int CompareTo(object obj) => obj is DGraphExtensionProperty other ? CompareTo(other) : -1; - - public static implicit operator DGraphExtensionProperty(MgExtensionProperty extensionProperty) => new(extensionProperty.Name); -} - -public static class Helpers -{ - public static DGraphExtensionProperty GetExtensionPropertyObject(string extensionPropertyName, guid extensionAppClientId) - { - return new DGraphExtensionProperty(extensionPropertyName, extensionAppClientId); - } - public static DGraphExtensionProperty GetExtensionPropertyObject((string extensionPropertyName, guid extensionAppClientId) extensionProperty) - { - return new DGraphExtensionProperty(extensionProperty.extensionPropertyName, extensionProperty.extensionAppClientId); - } - public static string GetExtensionPropertyName(this (string extensionPropertyName, guid extensionAppClientId) extensionProperty) - { - return new DGraphExtensionProperty(extensionProperty.extensionPropertyName, extensionProperty.extensionAppClientId).Name; - } -} diff --git a/src/MicrosoftGraph/Models/TargetObjectType.cs b/src/MicrosoftGraph/Models/TargetObjectType.cs deleted file mode 100644 index e7c0c682..00000000 --- a/src/MicrosoftGraph/Models/TargetObjectType.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Dgmjr.Graph; - -public enum TargetObjectType -{ - /// Users - User, - /// Groups - Group, - /// Contacts - Contact, - /// Devices - Device, - /// Organization - Organization, - /// Administrative Unit - AdministrativeUnit, - /// Application - Application -} diff --git a/src/MicrosoftGraph/Options/MicrosoftGraphOptions.cs b/src/MicrosoftGraph/Options/MicrosoftGraphOptions.cs deleted file mode 100644 index 37309f0f..00000000 --- a/src/MicrosoftGraph/Options/MicrosoftGraphOptions.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Dgmjr.Graph.Options; - -public class AzureAdB2CGraphOptions : Microsoft.Identity.Web.MicrosoftGraphOptions -{ - /// MicrosoftGraphOptions - public const string AppSettingsKey = nameof(AzureAdB2CGraphOptions); - - /// The of the Azure AD B2C extensions application - public guid AzureAdB2CExtensionsApplicationId { get; set; } - - public bool AppOnly { get; set; } = false; -} diff --git a/src/MicrosoftGraph/Options/PassphraseGeneratorOptions.cs b/src/MicrosoftGraph/Options/PassphraseGeneratorOptions.cs deleted file mode 100644 index 23dbf9a9..00000000 --- a/src/MicrosoftGraph/Options/PassphraseGeneratorOptions.cs +++ /dev/null @@ -1,29 +0,0 @@ -/* - * PasswordGenerator.cs - * - * Created: 2022-12-31-06:39:48 - * Modified: 2022-12-31-06:39:49 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2022-2023 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Identity; - -public class PassphraseGeneratorOptions -{ - public const string AppSettingsKey = nameof(PassphraseGenerator); - - public int WordCount { get; set; } = 4; - public int EmojiCount { get; set; } = 2; - public int SpecialCharacterCount { get; set; } = 1; - public int LowercaseCharacterCount { get; set; } = 1; - public int UppercaseCharacterCount { get; set; } = 1; - public int CharacterCount { get; set; } = 16; - public char[] SpecialCharacters { get; set; } = @"~`!@#$%^&*()_+-={}|[]\<>?,./""".ToCharArray(); - public char[] Emoji { get; set; } = - @"😀😃😄😁😆🥹😅😂🤣🥲☺️😊😇🙂🙃😉😌😍🥰😘😗😙😚😋😛😝😜🤪🤨🧐🤓😎🥸🤩🥳😏😒😞😔😟😕🙁☹️😣😖😫😩🥺😢😭😤😠😡🤬🤯😳🥵🥶😶‍🌫️😱😨😰😥😓🤗🤔🫣🤭🫢🫡🤫🫠🤥😶🫥😐🫤😑🫨😬🙄😯😦😧😮😲🥱😴🤤😪😮‍💨😵😵‍💫🤐🥴🤢🤮🤧😷🤒🤕🤑🤠😈👿👹👺🤡💩👻💀☠️👽👾🤖🐶🐱🐭🐹🐰🦊🐻🐼🐻‍❄️🐨🐯🦁🐮🐷🐽🐸🐵🙈🙉🙊🐒🐔🐧🐦🐤🐣🐥🪿🦆🐦‍⬛🦅🦉🦇🐺🐗🐴🦄🫎🐝🪱🐛🦋🐌🐞🐜🪰🪲🪳🦟🦗🕷️🕸️🦂🐢🐍🦎🦖🦕🐙🦑🪼🦐🦞🦀🐡🐠🐟🐬🐳🐋🦈🦭🐊🐅🐆🦓🦍🦧🦣🐘🦛🦏🐪🐫🦒🦘🦬🐃🐂🐄🫏🐎🐖🐏🐑🦙🐐🦌🐕🐩🦮🐕‍🦺🐈🐈‍⬛🪶🪽🐓🦃🦤🦚🦜🦢🦩🕊️🐇🦝🦨🦡🦫🦦🦥🐁🐀🐿️🦔🐾🐉🐲🌵🎄🌲🌳🌴🪵🌱🌿☘️🍀🎍🪴🎋🍃🍂🍁🪺🪹🍄🐚🪸🪨🌾💐🌷🌹🥀🪻🪷🌺🌸🌼🌻🌞🌝🌛🌜🌚🌕🌖🌗🌘🌑🌒🌓🌔🌙🌎🌍🌏🪐💫⭐️🌟✨⚡️☄️💥🔥🌪️🌈☀️🌤️⛅️🌥️☁️🌦️🌧️⛈️🌩️🌨️❄️☃️⛄️🌬️💨💧💦🫧☔️☂️🌊🌫️🍏🍎🍐🍊🍋🍌🍉🍇🍓🫐🍈🍒🍑🥭🍍🥥🥝🍅🍆🥑🫛🥦🥬🥒🌶️🫑🌽🥕🫒🧄🧅🥔🍠🫚🥐🥯🍞🥖🥨🧀🥚🍳🧈🥞🧇🥓🥩🍗🍖🦴🌭🍔🍟🍕🫓🥪🥙🧆🌮🌯🫔🥗🥘🫕🥫🫙🍝🍜🍲🍛🍣🍱🥟🦪🍤🍙🍚🍘🍥🥠🥮🍢🍡🍧🍨🍦🥧🧁🍰🎂🍮🍭🍬🍫🍿🍩🍪🌰🥜🫘🍯🥛🫗🍼🫖☕️🍵🧃🥤🧋🍶🍺🍻🥂🍷🥃🍸🍹🧉🍾🧊🥄🍴🍽️🥣🥡🥢🧂⚽️🏀🏈⚾️🥎🎾🏐🏉🥏🎱🪀🏓🏸🏒🏑🥍🏏🪃🥅⛳️🪁🛝🏹🎣🤿🥊🥋🎽🛹🛼🛷⛸️🥌🎿⛷️🏆🥇🥈🥉🏅🎖️🏵️🎗️🎫🎟️🎪🎭🩰🎨🎬🎤🎧🎼🎹🪇🥁🪘🎷🎺🪗🎸🪕🎻🪈🎲♟️🎯🎳🎮🎰🧩🚗🚕🚙🚌🚎🏎️🚓🚑🚒🚐🛻🚚🚛🚜🦯🦽🦼🩼🛴🚲🛵🏍️🛺🛞🚨🚔🚍🚘🚖🚡🚠🚟🚃🚋🚞🚝🚄🚅🚈🚂🚆🚇🚊🚉✈️🛫🛬🛩️💺🛰️🚀🛸🚁🛶⛵️🚤🛥️🛳️⛴️🚢🛟⚓️🪝⛽️🚧🚦🚥🚏🗺️🗿🗽🗼🏰🏯🏟️🎡🎢🎠⛲️⛱️🏖️🏝️🏜️🌋⛰️🗻🗻🏕️⛺️🛖🏠🏡🏘️🏚️🏗️🏭🏢🏬🏣🏤🏥🏦🏨🏪🏫🏩💒🏛️⛪️🕌🕍🛕🕋⛩️🛤️🛣️🗾🎑🏞️🌅🌄🌠🎇🎆🌇🌆🏙️🌃🌌🌉🌁⌚️📱📲💻⌨️🖥️🖨️🖱️🖲️🕹️🗜️💽💾💿📀📼📷📸📹🎥📽️🎞️📞☎️📟📠📺📻🎙️🎚️🎛️🧭⏱️⏲️⏰🕰️⌛️⏳📡🔋🪫🔌💡🔦🕯️🪔🧯🛢️💸💵💴💶💷🪙💰💳🪪💎⚖️🪜🧰🪛🔧🔨⚒️🛠️⛏️🪚🔩⚙️🪤🧱⛓️🧲🔫💣🧨🪓🔪🗡️⚔️🛡️🚬⚰️🪦⚱️🏺🔮📿🧿🪬💈⚗️🔭🔬🕳️🩻🩹🩺💊💉🩸🧬🦠🧫🧪🌡️🧹🪠🧺🧻🚽🚰🚿🛁🧽🪣🧴🛎️🔑🗝️🚪🪑🛋️🛏️🛌🧸🪆🖼️🪞🪟🛍️🛒🎁🎈🎏🎀🪄🪅🎊🎉🎎🪭🏮🎐🪩🧧✉️📩📨📧💌📥📤📦🏷️🪧📪📫📬📭📮📯📜📃📄📑🧾📊📈📉🗒️🗓️📆📅🗑️📇🗃️🗳️🗄️📋📁📂🗂️🗞️📰📓📔📒📕📗📘📙📚📖🔖🧷🔗📎🖇️📐📏🧮📌📍✂️🖊️🖋️✒️🖌️🖍️📝✏️🔍🔎🔏🔐🔒🔓🩷❤️🧡💛💚🩵💙💜🖤🩶🤍🤎💔❤️‍🔥❤️‍🩹❣️💕💞💓💗💖💘💝💟☮️✝️☪️🕉️☸️🪯✡️🔯🕎☯️☦️🛐⛎♈️♉️♊️♋️♌️♍️♎️♏️♐️♑️♒️♓️🆔⚛️🉑☢️☣️📴📳🈶🈚️🈸🈺🈷️✴️🆚💮🉐㊙️㊗️🈴🈵🈹🈲🅰️🅱️🆎🆑🅾️🆘❌⭕️🛑⛔️📛🚫💯💢♨️🚷🚯🚳🚱🔞📵🚭❗️❕❓❔‼️⁉️🔅🔆〽️⚠️🚸🔱⚜️🔰♻️✅🈯️💹❇️✳️❎🌐💠Ⓜ️🌀💤🏧🚾♿️🅿️🛗🈳🈂️🛂🛃🛄🛅🛜🚹🚺🚼⚧️🚻🚮🎦📶🈁🔣ℹ️🔤🔡🔠🆖🆗🆙🆒🆕🆓0️⃣1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟🔢#️⃣*️⃣⏏️▶️⏸️⏯️⏹️⏺️⏭️⏮️⏩️⏪️⏫️⏬️◀️🔼🔽➡️⬅️⬆️⬇️↗️↘️↙️↖️↕️↔️↪️↩️⤴️⤵️🔀🔁🔂🔄🔃🎵🎶➕➖➗✖️🟰♾️💲💱™️©️®️👁️‍🗨️🔚🔙🔛🔝🔜〰️➰➿✔️☑️🔘🔴🟠🟡🟢🔵🟣⚫️⚪️🟤🔺🔻🔸🔹🔶🔷🔳🔲▪️▫️◾️◽️◼️◻️🟥🟧🟨🟩🟦🟪⬛️⬜️🟫🔈🔇🔉🔊🔔🔕📣📢💬💭🗯️♠️♣️♥️♦️🃏🎴🀄️🕐🕑🕒🕓🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕦🕧".ToCharArray(); - public string[] WordList { get; set; } -} diff --git a/src/MicrosoftGraph/README.md b/src/MicrosoftGraph/README.md deleted file mode 100644 index 1035d479..00000000 --- a/src/MicrosoftGraph/README.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: -lastmod: 2023-36-31T14:36:04.3724-06:00Z -date: 2023-36-31T14:36:04.3726-06:00Z -license: MIT -slug: Dgmjr.Graph-readme -version: -authors: - - dgmjr; -description: Dgmjr.Graph Readme #TODO: write description for Dgmjr.Graph Readme -keywords: -- Dgmjr.Graph - - dgmjr - - dgmjr-io -type: readme ---- -# Dgmjr.Graph Readme - -## Package Description -## Getting Started -## Prerequisites -## Installation -## Usage -## Contributing -## Versioning -Built from [commit cbca982 on branch main at ] -(/tree/cbca98257951bbe23b2a8e9e1f6935c5c2b3b5d4) diff --git a/src/MicrosoftGraph/Services/ApplicationService.cs b/src/MicrosoftGraph/Services/ApplicationService.cs deleted file mode 100644 index 12a04179..00000000 --- a/src/MicrosoftGraph/Services/ApplicationService.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Dgmjr.Graph.Services; - -public class ApplicationService( - GraphServiceClient graph, - ILogger logger, - IOptionsMonitor options, - IOptionsMonitor msidOptions, - IDistributedCache cache -) : MsGraphService(graph, logger, options, msidOptions, cache), IApplicationService { } diff --git a/src/MicrosoftGraph/Services/DirectoryObjectsService.cs b/src/MicrosoftGraph/Services/DirectoryObjectsService.cs deleted file mode 100644 index cc86fb1c..00000000 --- a/src/MicrosoftGraph/Services/DirectoryObjectsService.cs +++ /dev/null @@ -1,54 +0,0 @@ -namespace Dgmjr.Graph.Services; - -public class DirectoryObjectsService( - GraphServiceClient graph, - ILogger logger, - IOptionsMonitor options, - IOptionsMonitor msidOptions, - IDistributedCache cache -) : MsGraphService(graph, logger, options, msidOptions, cache), IDirectoryObjectsService -{ - public async Task GetAsync( - string id, - CancellationToken cancellationToken = default - ) - { - return await Graph.DirectoryObjects[id].Request().GetAsync(cancellationToken); - } - - public async Task GetAsync( - string id, - string property, - CancellationToken cancellationToken = default - ) - { - return await Graph.DirectoryObjects[id] - .Request() - .Select(property) - .GetAsync(cancellationToken); - } - - public async Task CreateAsync( - DirectoryObject directoryObject, - CancellationToken cancellationToken = default - ) - { - return await Graph.DirectoryObjects.Request().AddAsync(directoryObject, cancellationToken); - } - - public async Task DeleteAsync(string id, CancellationToken cancellationToken = default) - { - await Graph.DirectoryObjects[id].Request().DeleteAsync(cancellationToken); - } - - public async Task UpdateAsync( - string id, - DirectoryObject directoryObject, - CancellationToken cancellationToken = default - ) - { - return await Graph.DirectoryObjects[id] - .Request() - .UpdateAsync(directoryObject, cancellationToken); - } -} diff --git a/src/MicrosoftGraph/Services/MsGraphService.cs b/src/MicrosoftGraph/Services/MsGraphService.cs deleted file mode 100644 index 3c00e56d..00000000 --- a/src/MicrosoftGraph/Services/MsGraphService.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace Dgmjr.Graph.Services; -using global::Dgmjr.Abstractions; - -public interface IMsGraphService : IHaveAGraphClient -{ - /// The client ID of the extensions application - guid ExtensionsAppClientId { get; } - - /// The client ID of the application registered in Azure AD that the Web app/API is registered with - guid ClientId { get; } - - /// Retrieves the application registered in Azure AD that the Web app/API is registered with - Task GetApplicationAsync(); - - /// Retrieves - /// - /// the list of extension properties registered with the extensions application - Task GetExtensionPropertiesAsync(CancellationToken cancellationToken = default); - - /// Retrieves - /// the extensions application registered with client ID - Task GetExtensionsApplicationAsync(); -} - -public class MsGraphService(GraphServiceClient graph, ILogger logger, IOptionsMonitor options, IOptionsMonitor msidOptions, IDistributedCache cache) : IMsGraphService -{ - private static readonly duration CacheDuration = duration.FromDays(1000); - private static readonly DateTimeOffset CacheExpiration = DateTimeOffset.UtcNow.Add(CacheDuration); - public ILogger Logger => logger; - private AzureAdB2CGraphOptions Options => options.CurrentValue; - private MicrosoftIdentityOptions MsidOptions => msidOptions.CurrentValue; - public guid ExtensionsAppClientId => Options.AzureAdB2CExtensionsApplicationId; - public guid ClientId => new(MsidOptions.ClientId); - protected IDistributedCache Cache => cache; - - public virtual GraphServiceClient Graph => graph; - - public async Task GetApplicationAsync() - { - return await Graph.Applications[ClientId.ToString()].Request().GetAsync(); - } - - public async Task GetExtensionsApplicationAsync() - { - return await Graph.Applications[ExtensionsAppClientId.ToString()].Request().GetAsync(); - } - - public async Task GetExtensionPropertiesAsync(CancellationToken cancellationToken = default) - { - await Cache.SetStringAsync("test", "test", CacheExpiration, cancellationToken: cancellationToken); - var extensionPropertiesJson = await Cache.GetStringAsync(CacheKeys.ExtensionProperties, cancellationToken); - MgExtensionProperty[]? extensionProperties; - if (extensionPropertiesJson is not null) - { - Logger.CacheHit(CacheKeys.ExtensionProperties); - extensionProperties = Deserialize(extensionPropertiesJson)!; - } - else - { - Logger.CacheMiss(CacheKeys.ExtensionProperties); - extensionProperties = - [..await Graph.DirectoryObjects.GetAvailableExtensionProperties().Request().PostAsync(cancellationToken)]; - await Cache.SetAsync(CacheKeys.ExtensionProperties, extensionProperties, CacheExpiration, cancellationToken: cancellationToken); - } - return extensionProperties; - } -} diff --git a/src/MicrosoftGraph/Services/PassphraseGenerator.cs b/src/MicrosoftGraph/Services/PassphraseGenerator.cs deleted file mode 100644 index 21cd3ef3..00000000 --- a/src/MicrosoftGraph/Services/PassphraseGenerator.cs +++ /dev/null @@ -1,90 +0,0 @@ -/* - * PasswordGenerator.cs - * - * Created: 2022-12-31-06:39:48 - * Modified: 2022-12-31-06:39:49 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2022-2023 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Identity; - -public class PassphraseGenerator(IOptionsMonitor options) - : IPassphraseGenerator -{ - private static readonly RandomNumberGenerator Random = RandomNumberGenerator.Create(); - private PassphraseGeneratorOptions Options => - options?.CurrentValue ?? throw new ArgumentNullException(nameof(options)); - private string[] WordList => Options.WordList; - private char[] SpecialCharacters => Options.SpecialCharacters; - private int WordCount => Options.WordCount; - private int EmojiCount => Options.EmojiCount; - private int SpecialCharacterCount => Options.SpecialCharacterCount; - private int LowercaseCharacterCount => Options.LowercaseCharacterCount; - private int UppercaseCharacterCount => Options.UppercaseCharacterCount; - private int CharacterCount => Options.CharacterCount; - private char[] Emoji => Options.Emoji; - - public string Generate() - { - var wordsToGo = WordCount; - var emojiToGo = EmojiCount; - var specialCharactersToGo = SpecialCharacterCount; - var lowercaseCharactersToGo = LowercaseCharacterCount; - var uppercaseCharactersToGo = UppercaseCharacterCount; - var charactersToGo = CharacterCount; - - var passphrase = new StringBuilder(); - - while ( - wordsToGo > 0 - || emojiToGo > 0 - || specialCharactersToGo > 0 - || lowercaseCharactersToGo > 0 - || uppercaseCharactersToGo > 0 - || charactersToGo > 0 - ) - { - var word = GetRandomWord(); - passphrase.Append(word); - wordsToGo--; - charactersToGo -= word.Length; - lowercaseCharactersToGo -= word.Count(char.IsLower); - uppercaseCharactersToGo -= word.Count(char.IsUpper); - - if (emojiToGo > 0) - { - var emoji = PickRandomElement(Emoji); - passphrase.Append(emoji); - emojiToGo--; - charactersToGo--; - } - - if (lowercaseCharactersToGo > 0) - { - var emoji = PickRandomElement(Emoji); - passphrase.Append(emoji); - emojiToGo--; - charactersToGo--; - } - - if (specialCharactersToGo > 0) - { - var specialCharacter = PickRandomElement(SpecialCharacters); - passphrase.Append(specialCharacter); - specialCharactersToGo--; - charactersToGo--; - } - } - - return passphrase.ToString(); - } - - private string GetRandomWord() => PickRandomElement(WordList); - - private static T PickRandomElement(T[] elements) => - elements.Skip(Random.NextInt32(elements.Length - 1)).First(); -} diff --git a/src/MicrosoftGraph/Services/UsersService.cs b/src/MicrosoftGraph/Services/UsersService.cs deleted file mode 100644 index a05cbfd9..00000000 --- a/src/MicrosoftGraph/Services/UsersService.cs +++ /dev/null @@ -1,188 +0,0 @@ -namespace Dgmjr.Graph.Services; -using User = Microsoft.Graph.User; - -public class UsersService(GraphServiceClient graph, ILogger logger, IOptionsMonitor options, IOptionsMonitor msidOptions, IDistributedCache cache) : MsGraphService(graph, logger, options, msidOptions, cache), IUsersService -{ - public async Task GetMeAsync(CancellationToken cancellationToken = default) - { - return await Graph.Me.Request().GetAsync(cancellationToken); - } - public async Task GetMyIdAsync(CancellationToken cancellationToken = default) - { - return new ((await GetMeAsync(cancellationToken)).Id); - } - - public async Task UpdateAsync(User user, CancellationToken cancellationToken = default) - { - return await Graph.Users[user.Id].Request().UpdateAsync(user, cancellationToken); - } - - public async Task UpdateAsync(guid id, string property, string value, CancellationToken cancellationToken = default) - => await UpdateAsync(id.ToString(), property, value, cancellationToken); - - public async Task UpdateAsync(string id, string property, string value, CancellationToken cancellationToken = default) - { - var user = await Graph.Users[id].Request().GetAsync(cancellationToken); - user.AdditionalData[property] = value; - return await Graph.Users[id].Request().UpdateAsync(user, cancellationToken); - } - - public async Task GetAsync(string id, CancellationToken cancellationToken = default) - { - return await Graph.Users[id].Request().GetAsync(cancellationToken); - } - - public async Task GetAsync(string id, string property, CancellationToken cancellationToken = default) - { - var extensionPropertyName = (property, ExtensionsAppClientId).GetExtensionPropertyName(); - return await Graph.Users[id].Request().Select(property).Select(extensionPropertyName).GetAsync(cancellationToken); - } - - public async Task CreateAsync(User user, CancellationToken cancellationToken = default) - { - return await Graph.Users.Request().AddAsync(user, cancellationToken); - } - - public async Task DeleteAsync(string id, CancellationToken cancellationToken = default) - { - await Graph.Users[id].Request().DeleteAsync(cancellationToken); - } - - public async Task IsInAppRoleAsync(string id, string appId, string appRoleId, CancellationToken cancellationToken = default) - => (await Graph.Users[id].Request().GetAsync(cancellationToken)).AppRoleAssignments.Any(a => a.AppRoleId == new guid(appRoleId) && a.ResourceId == new guid(appId)); - - public async Task AssignToAppRoleAsync(string userId, string appId, string appRoleId, CancellationToken cancellationToken = default) - => await AssignToAppRoleAsync(new guid(userId), new guid(appId), new guid(appRoleId), cancellationToken); - - public async Task AssignToAppRoleAsync(guid userId, guid appId, guid appRoleId, CancellationToken cancellationToken = default) - { - return await Graph.Users[userId.ToString()].AppRoleAssignments.Request().AddAsync(new AppRoleAssignment - { - PrincipalId = userId, - ResourceId = appId, - AppRoleId = appRoleId - }, cancellationToken); - } - - public async Task UnassignAppRoleAsync(string userId, string appId, string appRoleId, CancellationToken cancellationToken = default) - => await UnassignAppRoleAsync(new guid(userId), new(appId), new(appRoleId), cancellationToken); - - public async Task UnassignAppRoleAsync(guid userId, guid appId, guid appRoleId, CancellationToken cancellationToken = default) - { - var assignments = await Graph.Users[userId.ToString()].AppRoleAssignments.Request().GetAsync(cancellationToken); - var assignment = assignments.FirstOrDefault(a => a.AppRoleId == appRoleId && a.ResourceId == appId) ?? throw new KeyNotFoundException($"No app role assignment found for user {userId} with app {appId} and role {appRoleId}"); - await Graph.Users[userId.ToString()].AppRoleAssignments[assignment.Id].Request().DeleteAsync(cancellationToken); - } - - public async Task FindByEmailAsync( - string normalizedEmail, - CancellationToken cancellationToken = default - ) - { - return ( - await Graph.Users - .Request() - .Filter($"mail eq '{normalizedEmail}'") - .GetAsync(cancellationToken) - ).FirstOrDefault(); - } - - public async Task FindBySignInNameAsync(string name, CancellationToken cancellationToken = default) - { - try - { - // Get user by sign-in name - var result = (await Graph.Users - .Request() - .Filter($"identities/any(c:c/issuerAssignedId eq '{name}')") - .Select(e => new - { - e.DisplayName, - e.Id, - e.Identities - }) - .GetAsync(cancellationToken)) - .SingleOrDefault(); - - if (result != null) - { - Logger.LogInformation(Serialize(result)); - return result; - } - - Logger.LogError($"User with login name {name} not found."); - return null; - } - catch (Exception ex) - { - Logger.LogError(ex, "Error retrieving user by sign-in name."); - } - - return null; - } - - public async Task SetPasswordByUserId(string userId, string password, bool forceChangePasswordNextSignIn = false, CancellationToken cancellationToken = default) - { - Logger.LogInformation($"Looking for user with object ID '{userId}'..."); - - var user = new User - { - PasswordPolicies = "DisablePasswordExpiration,DisableStrongPassword", - PasswordProfile = new PasswordProfile - { - ForceChangePasswordNextSignIn = forceChangePasswordNextSignIn, - Password = password, - } - }; - - try - { - // Update user by object ID - await Graph.Users[userId] - .Request() - .UpdateAsync(user, cancellationToken); - - Logger.LogInformation($"User with object ID '{userId}' successfully updated."); - } - catch (ClientException ex) - { - Logger.LogError(ex, $"Error updating user with object ID '{userId}'."); - throw; - } - } - - public async Task> GetUsersWithCustomAttribute(GraphServiceClient graphClient, string attributeName, CancellationToken cancellationToken = default) - { - var extensionAttribute = new DGraphExtensionProperty(attributeName, ExtensionsAppClientId); - - Logger.LogInformation($"Getting list of users with the custom attributes '{attributeName}' (string)"); - - // Get all users (one page) - var result = await graphClient.Users - .Request() - .Select($"id,displayName,identities,{extensionAttribute}") - .GetAsync(cancellationToken); - - return [.. result]; - } - - // public async Task RemoveAppRoleByNameAsync(string userId, string appId, string appRoleName, CancellationToken cancellationToken = default) - // => await RemoveAppRoleByNameAsync(new guid(userId), new (appId), appRoleName); - - // public async Task RemoveAppRoleByNameAsync(guid userId, guid appId, string appRoleName, CancellationToken cancellationToken = default) - // { - // var assignments = await Graph.Users[userId.ToString()].AppRoleAssignments.Request().GetAsync(); - // graph..AppRoles.Request().Filter($"displayName eq '{appRoleName}'").GetAsync(); - // var assignment = assignments.FirstOrDefault(a => a..AppRoleId == appRoleId && a.ResourceId == appId); - // if (assignment is null) - // { - // throw new KeyNotFoundException($"No app role assignment found for user {userId} with app {appId} and role {appRoleId}"); - // } - // await Graph.Users[userId.ToString()].AppRoleAssignments[assignment.Id].Request().DeleteAsync(); - // } - - // public async Task GetAsync(string id, string property, string value, CancellationToken cancellationToken = default) - // { - // return await Graph.Users[id].Request().Filter($"{property} eq '{value}'").GetAsync(); - // } -} diff --git a/src/MicrosoftGraph/Telemetry/Activities.cs b/src/MicrosoftGraph/Telemetry/Activities.cs deleted file mode 100644 index d7d19513..00000000 --- a/src/MicrosoftGraph/Telemetry/Activities.cs +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Activities.cs - * - * Created: 2024-03-26T11:03:20-05:00 - * Modified: 2024-03-26T11:03:22-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2023 - 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -namespace Dgmjr.Graph.Telemetry; - -public static class Activities -{ - private static readonly Version AssemblyVersion = typeof(Activities).Assembly.GetName().Version; - - public static readonly ActivitySource ActivitySource = new(TraceNames.Basic, ServiceVersion); - - /// - /// Base ActivitySource - /// - public static readonly ActivitySource BasicActivitySource = - new(TraceNames.Basic, ServiceVersion); - - /// - /// Store ActivitySource - /// - public static readonly ActivitySource StoreActivitySource = - new(TraceNames.Store, ServiceVersion); - - /// - /// Cache ActivitySource - /// - public static readonly ActivitySource CacheActivitySource = - new(TraceNames.Cache, ServiceVersion); - - /// - /// Cache ActivitySource - /// - public static readonly ActivitySource ServiceActivitySource = - new(TraceNames.Services, ServiceVersion); - - /// - /// Detailed validation ActivitySource - /// - public static readonly ActivitySource ValidationActivitySource = - new(TraceNames.Validation, ServiceVersion); - - /// - /// Detailed validation ActivitySource - /// - public static readonly ActivitySource TokenAcquisitionActivitySource = - new(TraceNames.TokenAcquisition, ServiceVersion); - - /// - /// Service version - /// - public static readonly string ServiceVersion = - $"{AssemblyVersion.Major}.{AssemblyVersion.Minor}.{AssemblyVersion.Build}"; -} - -public static class TraceNames -{ - /// - /// Service name for base traces - /// - public const string Basic = "Dgmjr.Graph"; - - /// - /// Service name for store traces - /// - public const string Store = Basic + "." + nameof(Store) + "s"; - - /// - /// Service name for caching traces - /// - public const string Cache = Basic + "." + nameof(Cache); - - /// - /// Service name for caching traces - /// - public const string Services = Basic + "." + nameof(Services); - - /// - /// Service name for detailed validation traces - /// - public const string Validation = Basic + nameof(Validation); - - /// - /// Service name for detailed token acquisition traces - /// - public const string TokenAcquisition = Basic + "." + nameof(TokenAcquisition); - - public static readonly string ServiceVersion = Activities.ServiceVersion; -} diff --git a/src/MicrosoftGraph/TokenProviders/BearerTokenAuthenticationProvider.cs b/src/MicrosoftGraph/TokenProviders/BearerTokenAuthenticationProvider.cs deleted file mode 100644 index 686dd1e2..00000000 --- a/src/MicrosoftGraph/TokenProviders/BearerTokenAuthenticationProvider.cs +++ /dev/null @@ -1,33 +0,0 @@ -/* - * BearerTokenAuthenticationProvider.cs - * - * Created: 2024-12-26T12:12:00-05:00 - * Modified: 2024-12-26T12:12:00-05:00 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2023 - 2024 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - -using System.Net.Http; -using System.Threading.Tasks; - -using Microsoft.Kiota.Abstractions; -using Microsoft.Kiota.Abstractions.Authentication; - -using IAuthenticationProvider = Microsoft.Graph.IAuthenticationProvider; - -namespace Dgmjr.Graph; - -public class BearerTokenAuthenticationProvider(IAccessTokenProvider accessTokenProvider) - : BaseBearerTokenAuthenticationProvider(accessTokenProvider), - IAuthenticationProvider -{ - public Task AuthenticateRequestAsync(HttpRequestMessage request) - { - return base.AuthenticateRequestAsync(new HttpRequestMessageWrapper(request)); - } -} - -internal class HttpRequestMessageWrapper(HttpRequestMessage request) : RequestInformation { } diff --git a/src/MicrosoftGraph/TokenProviders/ClientSecretTokenProvider.cs b/src/MicrosoftGraph/TokenProviders/ClientSecretTokenProvider.cs deleted file mode 100644 index 2cf07827..00000000 --- a/src/MicrosoftGraph/TokenProviders/ClientSecretTokenProvider.cs +++ /dev/null @@ -1,22 +0,0 @@ -// using System; -// using System.Collections.Generic; -// using System.Threading; -// using System.Threading.Tasks; - -// using Microsoft.Kiota.Abstractions.Authentication; -// using Microsoft.Identity.Web; - -// namespace Dgmjr.Graph.TokenProviders; - -// public class ClientSecretTokenProvider(IOptionsMonitor options, ITokenAcquisition tokenAcquisition) : IAccessTokenProvider -// { -// private MicrosoftIdentityOptions Options => options.CurrentValue; -// public AllowedHostsValidator AllowedHostsValidator => new (ValidMsGraphHosts); - -// public async Task GetAuthorizationTokenAsync(Uri uri, Dictionary? additionalAuthenticationContext = null, CancellationToken cancellationToken = default) -// { -// TokenAcquirerAppTokenCredential tokenAcquisitionAppTokenCredential = new (tokenAcquisition); -// await tokenAcquisitionAppTokenCredential.GetTokenAsync(new Azure.Core.TokenRequestContext([MsGraphScopes.Default], tenantId: Options.TenantId), cancellationToken); - -// } -// } diff --git a/src/MicrosoftGraph/TokenProviders/TokenAcquisitionTokenProvider.cs b/src/MicrosoftGraph/TokenProviders/TokenAcquisitionTokenProvider.cs deleted file mode 100644 index 97a2bc7d..00000000 --- a/src/MicrosoftGraph/TokenProviders/TokenAcquisitionTokenProvider.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -using System.Security; -using System.Security.Claims; -using Microsoft.Identity.Web; -using Microsoft.Kiota.Abstractions.Authentication; - -using ClaimsPrincipal = System.Security.Claims.ClaimsPrincipal; - -namespace Dgmjr.Graph.TokenProviders -{ - /// - /// Access token provider used during login. - /// - /// - /// Initializes a new instance of the class. - /// - /// The service to use to acquire tokens. - /// The permission scopes to use for the token request. - /// The user's . - /// Thrown if the is null. - public class TokenAcquisitionTokenProvider( - ITokenAcquisition tokenAcquisition, - string[] scopes, - ClaimsPrincipal? user - ) : IAccessTokenProvider - { - private readonly string[] validHosts = - { - "graph.microsoft.com", - "graph.microsoft.us", - "dod-graph.microsoft.us", - "graph.microsoft.de", - "microsoftgraph.chinacloudapi.cn", - }; - private readonly ClaimsPrincipal _user = - user ?? throw new SecurityException("User claims principal is required."); - - /// - /// Gets the allowed host validator. - /// - public AllowedHostsValidator AllowedHostsValidator => new(validHosts); - - /// - /// Gets an access token for the user. - /// - /// The API URI of the request that the token will be added to. - /// Additional name value pairs to add to the token request. - /// The cancellation token. - /// The access token. - /// Thrown if the URI is not HTTPS. - public async Task GetAuthorizationTokenAsync( - Uri uri, - Dictionary? additionalAuthenticationContext = null, - CancellationToken cancellationToken = default - ) - { - if (!AllowedHostsValidator.IsUrlHostValid(uri)) - { - return string.Empty; - } - - if (uri.Scheme != "https") - { - throw new ArgumentOutOfRangeException(nameof(uri), "URL must use https."); - } - - return await tokenAcquisition.GetAccessTokenForUserAsync(scopes, user: _user); - } - } -} diff --git a/src/MicrosoftGraph/icon.png b/src/MicrosoftGraph/icon.png deleted file mode 100644 index db07a039..00000000 Binary files a/src/MicrosoftGraph/icon.png and /dev/null differ diff --git a/src/Mvc/Dgmjr.AspNetCore.Mvc.csproj b/src/Mvc/Dgmjr.AspNetCore.Mvc.csproj index d97fb127..d9f9a22a 100644 --- a/src/Mvc/Dgmjr.AspNetCore.Mvc.csproj +++ b/src/Mvc/Dgmjr.AspNetCore.Mvc.csproj @@ -13,7 +13,7 @@ net6.0;net8.0 - mvc + net8.0 This package contains a set of extensions and things for ASP.NET Core MVC @@ -30,6 +30,7 @@ + @@ -44,5 +45,8 @@ + + + diff --git a/src/Mvc/IHostApplicationBuilderMvcExtensions.cs b/src/Mvc/IHostApplicationBuilderMvcExtensions.cs index 618f72d2..5c21c0fb 100644 --- a/src/Mvc/IHostApplicationBuilderMvcExtensions.cs +++ b/src/Mvc/IHostApplicationBuilderMvcExtensions.cs @@ -11,6 +11,7 @@ namespace Microsoft.Extensions.DependencyInjection; using Microsoft.Identity.Web.UI; using Microsoft.Extensions.Logging; using static Dgmjr.AspNetCore.Mvc.ServiceNames; +using Microsoft.AspNetCore.Components.Server; public static class IHostApplicationBuilderMvcExtensions { @@ -81,9 +82,11 @@ public static WebApplicationBuilder AddMvc( mvcBuilder.AddMicrosoftIdentityUI(); } - if (mvcOptions.AddMvcConventions) + if (mvcOptions.AddRazorComponents) { - // mvcBuilder.AddMvcOptions(options => builder.Configuration.Bind(configurationSectionKey, options)); + logger?.SettingUpMvcService(RazorComponents); + // Microsoft.Extensions.DependencyInjection.RazorComponentsServiceCollectionExtensions.AddServerSideBlazor(builder.Services); + // builder.Services.AddRazorComponents(); } if (mvcOptions.AddJsonOptions) diff --git a/src/Mvc/MvcOptions.cs b/src/Mvc/MvcOptions.cs index 3441f46c..119e12c0 100644 --- a/src/Mvc/MvcOptions.cs +++ b/src/Mvc/MvcOptions.cs @@ -27,8 +27,12 @@ public MvcOptions() public virtual bool AddControllersWithViews { get; set; } = false; public virtual bool AddControllersAsServices { get; set; } = false; - /// if you want to add controllers with views, otherwise + /// if you want to add Razor pages, otherwise public virtual bool AddRazorPages { get; set; } = false; + /// if you want to add Razor components, otherwise + public virtual bool AddRazorComponents { get; set; } = false; + /// if you want to add interactive server components, otherwise + public virtual bool AddInteractiveServerComponents { get; set; } = false; /// if you want to add controllers with views, otherwise /// public virtual bool AddControllersAsServices { get; set; } = false; @@ -90,6 +94,10 @@ public MvcOptions() /// public virtual bool ReturnHttpNotAcceptable { get; set; } = mvc.ReturnHttpNotAcceptable; + /// if you want to use antiforgery, otherwise + /// !!! Only supported in .NET 8.0+ !!!! Ignored otherwise. + public virtual bool UseAntiforgery { get; set; } = true; + /// public virtual IDictionary CacheProfiles { get; set; } = mvc.CacheProfiles; diff --git a/src/Mvc/ServiceNames.cs b/src/Mvc/ServiceNames.cs index 0be1d25d..d4cd7ab1 100644 --- a/src/Mvc/ServiceNames.cs +++ b/src/Mvc/ServiceNames.cs @@ -12,4 +12,5 @@ public static class ServiceNames public const string XmlDataContractSerializerFormatters = nameof(XmlDataContractSerializerFormatters); public const string Cors = nameof(Cors); public const string MicrosoftIdentityUI = nameof(MicrosoftIdentityUI); + public const string RazorComponents = nameof(RazorComponents); }