Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 57 additions & 21 deletions api/referenceApi.sln
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 15.0.26124.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{07CC6F73-F414-4B07-8EE0-80ED98146110}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "referenceApp.Api", "src\referenceApp.Api\referenceApp.Api.csproj", "{597E84E7-C7C5-44F6-B894-81A48289DAB2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "referenceApp.Api", "src\referenceApp.Api\referenceApp.Api.csproj", "{597E84E7-C7C5-44F6-B894-81A48289DAB2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "referenceApp.Lib", "src\referenceApp.Lib\referenceApp.Lib.csproj", "{57673027-7BD6-46AA-807D-F38FD871E407}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "referenceApp.Lib", "src\referenceApp.Lib\referenceApp.Lib.csproj", "{57673027-7BD6-46AA-807D-F38FD871E407}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{176A31E6-D421-4B7C-B712-3E7EDA86FDD9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "referenceApp.Lib.Tests", "tests\referenceApp.Lib.Tests\referenceApp.Lib.Tests.csproj", "{177B2EB4-4F50-4EC2-9769-43936156F235}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "referenceApp.Lib.Tests", "tests\referenceApp.Lib.Tests\referenceApp.Lib.Tests.csproj", "{177B2EB4-4F50-4EC2-9769-43936156F235}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "referenceApp.Persistence", "src\referenceApp.Persistence\referenceApp.Persistence.csproj", "{CA0AD3FD-4047-4EFB-864B-F380203DEA5D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "referenceApp.Persistence", "src\referenceApp.Persistence\referenceApp.Persistence.csproj", "{CA0AD3FD-4047-4EFB-864B-F380203DEA5D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "referenceApp.Azure", "src\referenceApp.Azure\referenceApp.Azure.csproj", "{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "referenceApp.Common", "src\referenceApp.Common\referenceApp.Common.csproj", "{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "referenceApp.PowerBi", "src\referenceApp.PowerBi\referenceApp.PowerBi.csproj", "{03E47D01-B704-4DCA-8597-0A36078B1A0B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -24,9 +30,6 @@ Global
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{597E84E7-C7C5-44F6-B894-81A48289DAB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{597E84E7-C7C5-44F6-B894-81A48289DAB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
Expand Down Expand Up @@ -76,23 +79,56 @@ Global
{CA0AD3FD-4047-4EFB-864B-F380203DEA5D}.Release|x64.Build.0 = Release|Any CPU
{CA0AD3FD-4047-4EFB-864B-F380203DEA5D}.Release|x86.ActiveCfg = Release|Any CPU
{CA0AD3FD-4047-4EFB-864B-F380203DEA5D}.Release|x86.Build.0 = Release|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Debug|x64.ActiveCfg = Debug|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Debug|x64.Build.0 = Debug|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Debug|x86.ActiveCfg = Debug|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Debug|x86.Build.0 = Debug|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Release|Any CPU.Build.0 = Release|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Release|x64.ActiveCfg = Release|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Release|x64.Build.0 = Release|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Release|x86.ActiveCfg = Release|Any CPU
{013F9267-6307-4EFE-A4BE-93BF0F180D46}.Release|x86.Build.0 = Release|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Debug|x64.ActiveCfg = Debug|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Debug|x64.Build.0 = Debug|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Debug|x86.ActiveCfg = Debug|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Debug|x86.Build.0 = Debug|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Release|Any CPU.Build.0 = Release|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Release|x64.ActiveCfg = Release|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Release|x64.Build.0 = Release|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Release|x86.ActiveCfg = Release|Any CPU
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A}.Release|x86.Build.0 = Release|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Debug|x64.ActiveCfg = Debug|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Debug|x64.Build.0 = Debug|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Debug|x86.ActiveCfg = Debug|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Debug|x86.Build.0 = Debug|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Release|Any CPU.Build.0 = Release|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Release|x64.ActiveCfg = Release|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Release|x64.Build.0 = Release|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Release|x86.ActiveCfg = Release|Any CPU
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A}.Release|x86.Build.0 = Release|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Debug|x64.ActiveCfg = Debug|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Debug|x64.Build.0 = Debug|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Debug|x86.ActiveCfg = Debug|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Debug|x86.Build.0 = Debug|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Release|Any CPU.Build.0 = Release|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Release|x64.ActiveCfg = Release|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Release|x64.Build.0 = Release|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Release|x86.ActiveCfg = Release|Any CPU
{03E47D01-B704-4DCA-8597-0A36078B1A0B}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{597E84E7-C7C5-44F6-B894-81A48289DAB2} = {07CC6F73-F414-4B07-8EE0-80ED98146110}
{57673027-7BD6-46AA-807D-F38FD871E407} = {07CC6F73-F414-4B07-8EE0-80ED98146110}
{177B2EB4-4F50-4EC2-9769-43936156F235} = {176A31E6-D421-4B7C-B712-3E7EDA86FDD9}
{CA0AD3FD-4047-4EFB-864B-F380203DEA5D} = {07CC6F73-F414-4B07-8EE0-80ED98146110}
{2C7DAA8A-0DF3-42AE-9B62-E3B4D5A7EB7A} = {07CC6F73-F414-4B07-8EE0-80ED98146110}
{A6B2C9D7-9A41-4A5B-B4E5-EC0CCE41D56A} = {07CC6F73-F414-4B07-8EE0-80ED98146110}
{03E47D01-B704-4DCA-8597-0A36078B1A0B} = {07CC6F73-F414-4B07-8EE0-80ED98146110}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CCE2CF6B-53E0-4D6F-8C45-1CA22DA16BEE}
EndGlobalSection
EndGlobal
57 changes: 53 additions & 4 deletions api/src/referenceApp.Api/Controllers/ApiControllerBase.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,71 @@
using MediatR;
using System;
using System.Net;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.FeatureManagement;
using referenceApp.Api.System;
using referenceApp.Common.Models;
using referenceApp.Common.Models.System;

namespace referenceApp.Api.Controllers
{
[ApiController]
[Route("api/[controller]")]
public abstract class ApiControllerBase : ControllerBase
{
protected readonly IFeatureManager FeatureManager;
protected readonly ISettingsData SettingsData;
private readonly IUserSecurityService _userSecurity;
protected readonly IFeatureManager _featureManager;
private IMediator _mediator;

protected IMediator Mediator => _mediator ?? (_mediator = ControllerContext.HttpContext.RequestServices.GetService<IMediator>());

public ApiControllerBase(IFeatureManager featureManager)
public ApiControllerBase(IFeatureManager featureManager, IUserSecurityService userSecurity, ISettingsData settingsData)
{
FeatureManager = featureManager;
_featureManager = featureManager;
_userSecurity = userSecurity;
SettingsData = settingsData;

if (SettingsData?.UserProfile == null)
{
string env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
// ToDo TESTING Swagger: Developers change the AAD object id of the user that you want to do Swagger testing with.
// Uncomment [Authorize] attrbibute in derived controller class when done testing and before pushing changes.
if (env != null && env.Equals("Development", StringComparison.CurrentCultureIgnoreCase))
_userSecurity.LoadTestUser("59c343d1-9306-00aa-a09b-a13fb65867bf");
//_userSecurity.LoadTestUser(UserTypeEnum.Admin);
}
}

/// <summary>
/// Returns the appropriate ActionResult type for the provided model object that reflects either
/// a 200 success, 400 invalid data, or 500 program error condition.
/// </summary>
protected ActionResult ModelResponse(IBaseResponseModel model)
{
if (model == null)
throw new ArgumentNullException(nameof(model), "An instance of IBaseResponseModel is required when using the controller base ModelResponse method.");
if (model.Success)
{
return Ok(model);
}

if (string.IsNullOrWhiteSpace(model.ErrorDetail))
{
return BadRequest(model);
}
// treat any other condition a program error.
return StatusCode((int)HttpStatusCode.InternalServerError, model);
}

/// <summary>
/// Returns a new instance of the BaseResponseModel in an ActionResult type of 200 success.
/// </summary>
protected ActionResult NoDataResponse()
{
return Ok(new BaseResponseModel());
}

}
}
61 changes: 61 additions & 0 deletions api/src/referenceApp.Api/Controllers/ReportController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.FeatureManagement;
using referenceApp.Api.System;
using referenceApp.Common.Models.System;
using referenceApp.PowerBi.Models;
using referenceApp.PowerBi;
using System;
using System.Threading.Tasks;
using referenceApp.Lib.Report.Commands;
using referenceApp.Lib.Report.Queries;
using Microsoft.AspNetCore.Authorization;

namespace referenceApp.Api.Controllers
{
[Authorize]
[Route("api/[controller]/[action]")]
public class ReportController : ApiControllerBase
{
private readonly IPowerBiEmbedService _powerBiService;
private readonly IOptions<PowerBIConfigModel> _powerBiOptions;

public ReportController(IFeatureManager featureManager, IUserSecurityService userSecurity, ISettingsData settingsData, IPowerBiEmbedService powerBiService, IOptions<PowerBIConfigModel> powerBiOptions)
: base(featureManager, userSecurity, settingsData)
{
_powerBiService = powerBiService ?? throw new ArgumentNullException(nameof(powerBiService));
_powerBiOptions = powerBiOptions ?? throw new ArgumentNullException(nameof(powerBiOptions));
}

[HttpGet]
[Produces("application/json")]
public async Task<ActionResult<ReportEmbedResponseModel>> GetReportIdEmbedToken(int reportEnumId)
{
// get new Embed Token and report info
var reportEmbedResponse = await Mediator.Send(new GetReportEmbedQuery(new ReportEmbedRequestModel() { ReportEnumId = reportEnumId }));

// return report info with EmbedParameters needed for UI Http Request to Power BI server
return ModelResponse(reportEmbedResponse);
}

[HttpPost]
public async Task<IActionResult> ExportReport(ExportReportRequestModel request)
{

var response = await Mediator.Send(new ExportReportCommand(request));
if (response.Success && response.ReportStream != null)
{
//response.ReportStream.Flush();

var file = new FileStreamResult(response.ReportStream, response.DownloadMimeType);
file.FileDownloadName = response.ReportName + response.ResourceFileExtension;
return file;
}
else
{
return ModelResponse(response);
}
}

}
}
29 changes: 29 additions & 0 deletions api/src/referenceApp.Api/Controllers/SystemController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement;
using referenceApp.Api.System;
using referenceApp.Common.Models.System;

namespace referenceApp.Api.Controllers
{
[Authorize]
[Route("api/[controller]/[action]")]
public class SystemController : ApiControllerBase
{
public SystemController(IFeatureManager featureManager, IUserSecurityService userSecurity, ISettingsData settingsData)
: base(featureManager, userSecurity, settingsData)
{
}

[HttpGet]
[Produces("application/json")]
public async Task<ActionResult<UserProfileModel>> GetUserProfile()
{
// ToDo System Security: NOTE: User profile is loaded and validated on every api call from the OnTokenValidated event setup in the Startup class. No input needed; only the header token is needed.
// to test api using swagger, comment out [Authorize] attributes of the controller/method and change which test user to use in controller base class.
return ModelResponse(await Task.FromResult(SettingsData.UserProfile));
}
}
}
5 changes: 4 additions & 1 deletion api/src/referenceApp.Api/Controllers/TodoController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
using referenceApp.Lib.Todos.Models;
using referenceApp.Lib.Todos.Queries;
using referenceApp.Lib.Todos.ToggleTodoComplete;
using referenceApp.Api.System;
using referenceApp.Common.Models.System;

namespace referenceApp.Api.Controllers
{
public class TodoController : ApiControllerBase
{
public TodoController(IFeatureManager featureManager) : base(featureManager)
public TodoController(IFeatureManager featureManager, IUserSecurityService userSecurity, ISettingsData settingsData)
: base(featureManager, userSecurity, settingsData)
{
}

Expand Down
4 changes: 2 additions & 2 deletions api/src/referenceApp.Api/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"referenceApp.Api": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
Expand Down
Loading