Skip to content

Commit

Permalink
Adding AadSmartOnFhirProxy
Browse files Browse the repository at this point in the history
* Adding AadSmartOnFhirProxy
* Adding AadSmartOnFhirProxy E2E Tests
* Adding CORS parameters to template
* Adding SmartLauncher Sample App
  • Loading branch information
hansenms committed Dec 19, 2018
1 parent cf4239c commit 3d1898e
Show file tree
Hide file tree
Showing 25 changed files with 1,116 additions and 4 deletions.
12 changes: 12 additions & 0 deletions Microsoft.Health.Fhir.sln
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
testauthenvironment.json = testauthenvironment.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B5F2D2DF-D0C7-4861-8259-F6A041DB9854}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{80E8C5D3-E02C-49C0-969B-0C3A02FA1FF4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartLauncher", "samples\apps\SmartLauncher\SmartLauncher.csproj", "{49CA3B9D-7A22-43E0-A434-B0EC38D119A5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -104,6 +110,10 @@ Global
{CA276939-8071-4734-9FE4-ADC825B72116}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA276939-8071-4734-9FE4-ADC825B72116}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA276939-8071-4734-9FE4-ADC825B72116}.Release|Any CPU.Build.0 = Release|Any CPU
{49CA3B9D-7A22-43E0-A434-B0EC38D119A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{49CA3B9D-7A22-43E0-A434-B0EC38D119A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49CA3B9D-7A22-43E0-A434-B0EC38D119A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49CA3B9D-7A22-43E0-A434-B0EC38D119A5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -123,6 +133,8 @@ Global
{E2C2B117-32CD-449F-A4A8-4C8BA874D693} = {8AD2A324-DAB5-4380-94A5-31F7D817C384}
{614DE061-52A0-4471-A3F1-50C9C907FFDB} = {8AD2A324-DAB5-4380-94A5-31F7D817C384}
{CA276939-8071-4734-9FE4-ADC825B72116} = {B70945F4-01A6-4351-955B-C4A2943B5E3B}
{80E8C5D3-E02C-49C0-969B-0C3A02FA1FF4} = {B5F2D2DF-D0C7-4861-8259-F6A041DB9854}
{49CA3B9D-7A22-43E0-A434-B0EC38D119A5} = {80E8C5D3-E02C-49C0-969B-0C3A02FA1FF4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E370FB31-CF95-47D1-B1E1-863A77973FF8}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ function Add-AadTestAuthEnvironment {

if ($publicClient) {
Grant-ClientAppAdminConsent -AppId $aadClientApplication.AppId -TenantAdminCredential $TenantAdminCredential

# The public client (native app) is being used as SMART on FHIR client app in testing.
New-FhirServerSmartClientReplyUrl -AppId $aadClientApplication.AppId -FhirServerUrl $fhirServiceAudience -ReplyUrl "https://localhost:6001/sampleapp/index.html"
}

$environmentClientApplications += @{
Expand Down
18 changes: 18 additions & 0 deletions samples/apps/SmartLauncher/Models/SmartLauncherConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------

using System.Collections.Generic;

namespace SmartLauncher
{
public class SmartLauncherConfig
{
public string FhirServerUrl { get; set; }

public string DefaultSmartAppUrl { get; set; }

public string ClientId { get; set; }
}
}
29 changes: 29 additions & 0 deletions samples/apps/SmartLauncher/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace SmartLauncher
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
27 changes: 27 additions & 0 deletions samples/apps/SmartLauncher/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:1474",
"sslPort": 44335
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"smart_launcher": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
27 changes: 27 additions & 0 deletions samples/apps/SmartLauncher/SmartLauncher.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<IsPackable>true</IsPackable>
<CodeAnalysisRuleSet>..\..\..\CustomAnalysisRules.ruleset</CodeAnalysisRuleSet>
<UserSecretsId>SmartLauncher_3d9536f4-982c-4334-83df-890fb8ae70e6</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<AdditionalFiles Include="..\..\..\stylecop.json" Link="stylecop.json" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="wwwroot/sampleapp/launch.html" />
<EmbeddedResource Include="wwwroot/sampleapp/index.html" />
<EmbeddedResource Include="wwwroot/index.html" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61" />
</ItemGroup>

</Project>
58 changes: 58 additions & 0 deletions samples/apps/SmartLauncher/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Newtonsoft.Json;

namespace SmartLauncher
{
public class Startup
{
public Startup(IConfiguration configuration)
{
this.Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseDefaultFiles();
app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly(), "SmartLauncher.wwwroot") });

app.Map("/config", a =>
{
a.Run(async (context) =>
{
SmartLauncherConfig config = new SmartLauncherConfig();
this.Configuration.Bind(config);
await context.Response.WriteAsync(JsonConvert.SerializeObject(config));
});
});
}
}
}
5 changes: 5 additions & 0 deletions samples/apps/SmartLauncher/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"FhirServerUrl": "https://localhost:44348",
"ClientId": "APP-ID",
"DefaultSmartAppUrl": "/sampleapp/launch.html"
}
99 changes: 99 additions & 0 deletions samples/apps/SmartLauncher/wwwroot/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<title>Microsoft FHIR Server SMART on FHIR App Launcher</title>

</head>
<body>
<div class="container">
<h1>Microsoft FHIR Server SMART on FHIR App Launcher</h1>
<div class="row">
<h2>Launch parameters</h2>
<div class="form-group col-xs-8">
<label for="patient">Patient:</label>
<input type="text" id="patient" class="form-control" />
<label for="encounter">Encounter:</label>
<input type="text" id="encounter" class="form-control" />
<label for="practitioner">Practitioner:</label>
<input type="text" id="practitioner" class="form-control" />
<label for="appurl">Appliction URL:</label>
<input type="text" id="appurl" class="form-control" />
<label for="fhirurl">FHIR Server URL:</label>
<input type="text" id="fhirurl" class="form-control" />
</div>
</div>
<div class="row">
<h2>Launch context</h2>
<div class="form-group col-xs-8">
<textarea class="form-control" rows="5" id="launchContext" readonly>

</textarea>
</div>
</div>

<div class="row">
<h2>Launch URL</h2>
<div class="form-group col-xs-8">
<input type=text class="form-control disabled" id="launchUrl" readonly />
<button id="launchButton" style="margin-top: 5px;" class="btn btn-success" onclick="window.open($('#launchUrl').val(),'_blank')">Launch</button>
</div>
</div>
</div>

<script>
function updateLaunchQuery()
{
var launchContext = {};

if ($('#patient').val().length)
{
launchContext.patient = $('#patient').val();
}

if ($('#encounter').val().length)
{
launchContext.encounter = $('#encounter').val();
}

if ($('#practitioner').val().length)
{
launchContext.practioner = $('#practitioner').val();
}

var queryString = 'launch=' + encodeURIComponent(btoa(JSON.stringify(launchContext)));

if ($('#fhirurl').val().length)
{
queryString += '&iss=' + encodeURIComponent($('#fhirurl').val());
}

$('#launchContext').val(JSON.stringify(launchContext, undefined, 2));

$('#launchUrl').val($('#appurl').val() + '?' + queryString);

}


$('#patient').on('input', updateLaunchQuery);
$('#encounter').on('input', updateLaunchQuery);
$('#practitioner').on('input', updateLaunchQuery);
$('#appurl').on('input', updateLaunchQuery);
$('#fhirurl').on('input', updateLaunchQuery);


$.getJSON( '/config', function (appConfig) {
$('#appurl').val(appConfig.DefaultSmartAppUrl);
$('#fhirurl').val(appConfig.FhirServerUrl);
updateLaunchQuery();
});

</script>

</body>
</html>
45 changes: 45 additions & 0 deletions samples/apps/SmartLauncher/wwwroot/sampleapp/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>Sample app</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fhir-js-client@1.0.0/dist/fhir-client.min.js"></script>
</head>
<body>

<div class="container">
<h1>Microsoft FHIR Server SMART on FHIR Sample App</h1>

<div class="row">
<h2>Patient Resource</h2>
<textarea id="patientfield" style="width: 20cm; height: 5cm;"></textarea>
</div>

<div class="row">
<h2>Token Response</h2>
<textarea id="tokenresponsefield" style="width: 20cm; height: 5cm;"></textarea>
</div>
</div>

<script type="text/javascript">
function log(txt) {
document.getElementsByTagName("pre")[0].innerText += txt + "\n";
}

FHIR.oauth2.ready(function(client) {
$.when(client.patient.read()).then(
function(patient){
$('#patientfield').val(JSON.stringify(patient, null, 4));
$('#tokenresponsefield').val(JSON.stringify(client.tokenResponse, null, 4));
},
function(error){
console.log("Error:\n" + error);
}
);
});
</script>

</body>
</html>
20 changes: 20 additions & 0 deletions samples/apps/SmartLauncher/wwwroot/sampleapp/launch.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fhir-js-client@1.0.0/dist/fhir-client.min.js"></script>
<script>

var launchUri = window.location.protocol + "//" + window.location.host + window.location.pathname;
var redirectUri = launchUri.replace("launch.html","index.html");
$.getJSON( '/config', function (appConfig) {
FHIR.oauth2.authorize({
"client_id": appConfig.ClientId,
"scope" : "openid profile",
"redirect_uri": redirectUri
});
});
</script>
</head>
<body>Loading...</body>
</html>
2 changes: 1 addition & 1 deletion samples/scripts/PowerShell/FhirServer/FhirServer.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
CompanyName = 'https://microsoft.com'
Description = 'PowerShell Module for managing Azure Active Directory registrations and users for Microsoft FHIR Server.'
PowerShellVersion = '3.0'
FunctionsToExport = 'Remove-FhirServerApplicationRegistration', 'New-FhirServerClientApplicationRegistration', 'New-FhirServerApiApplicationRegistration', 'Get-FhirServerAzureAdAccessToken', 'Set-FhirServerApiApplicationRoles','Set-FhirServerClientAppRoleAssignments','Set-FhirServerUserAppRoleAssignments'
FunctionsToExport = 'Remove-FhirServerApplicationRegistration', 'New-FhirServerClientApplicationRegistration', 'New-FhirServerApiApplicationRegistration', 'Get-FhirServerAzureAdAccessToken', 'Set-FhirServerApiApplicationRoles','Set-FhirServerClientAppRoleAssignments','Set-FhirServerUserAppRoleAssignments','New-FhirServerSmartClientReplyUrl'
CmdletsToExport = @()
AliasesToExport = @()
}
Expand Down
Loading

0 comments on commit 3d1898e

Please sign in to comment.