config/build work

Still not pulling JWT payloads; validates and returns 404 :/
This commit is contained in:
Daniel J. Summers 2018-08-04 09:42:23 -05:00
parent 0f95d11bcd
commit e4d00b4157
7 changed files with 71 additions and 24 deletions

6
.gitignore vendored
View File

@ -254,8 +254,8 @@ paket-files/
# Compiled files / application # Compiled files / application
src/api/build src/api/build
src/public/index.html src/api/MyPrayerJournal.Api/wwwroot/index.html
src/public/static src/api/MyPrayerJournal.Api/wwwroot/static
src/config.json src/api/MyPrayerJournal.Api/appsettings.development.json
/build /build
src/*.exe src/*.exe

View File

@ -1,8 +1,9 @@
/// HTTP handlers for the myPrayerJournal API /// HTTP handlers for the myPrayerJournal API
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module MyPrayerJournal.Handlers module MyPrayerJournal.Api.Handlers
open Giraffe open Giraffe
open MyPrayerJournal
open System open System
module Error = module Error =
@ -17,7 +18,7 @@ module Error =
/// Handle 404s from the API, sending known URL paths to the Vue app so that they can be handled there /// Handle 404s from the API, sending known URL paths to the Vue app so that they can be handled there
let notFound : HttpHandler = let notFound : HttpHandler =
fun next ctx -> fun next ctx ->
let vueApp () = htmlFile "/index.html" next ctx let vueApp () = htmlFile "wwwroot/index.html" next ctx
match true with match true with
| _ when ctx.Request.Path.Value.StartsWith "/answered" -> vueApp () | _ when ctx.Request.Path.Value.StartsWith "/answered" -> vueApp ()
| _ when ctx.Request.Path.Value.StartsWith "/journal" -> vueApp () | _ when ctx.Request.Path.Value.StartsWith "/journal" -> vueApp ()
@ -31,6 +32,8 @@ module Error =
module private Helpers = module private Helpers =
open Microsoft.AspNetCore.Http open Microsoft.AspNetCore.Http
open Microsoft.AspNetCore.Authorization
open System.Threading.Tasks
/// Get the database context from DI /// Get the database context from DI
let db (ctx : HttpContext) = let db (ctx : HttpContext) =
@ -47,6 +50,21 @@ module private Helpers =
/// The "now" time in JavaScript /// The "now" time in JavaScript
let jsNow () = let jsNow () =
DateTime.Now.Subtract(DateTime (1970, 1, 1)).TotalSeconds |> int64 |> (*) 1000L DateTime.Now.Subtract(DateTime (1970, 1, 1)).TotalSeconds |> int64 |> (*) 1000L
let notAuthorized : HttpHandler =
setStatusCode 403 >=> fun _ _ -> Task.FromResult<HttpContext option> None
/// Handler to require authorization
let authorize : HttpHandler =
fun next ctx ->
task {
let auth = ctx.GetService<IAuthorizationService>()
let! result = auth.AuthorizeAsync (ctx.User, "LoggedOn")
Console.WriteLine (sprintf "*** Auth succeeded = %b" result.Succeeded)
match result.Succeeded with
| true -> return! next ctx
| false -> return! notAuthorized next ctx
}
/// Strongly-typed models for post requests /// Strongly-typed models for post requests
@ -87,7 +105,8 @@ module Journal =
/// GET /api/journal /// GET /api/journal
let journal : HttpHandler = let journal : HttpHandler =
fun next ctx -> authorize
>=> fun next ctx ->
match user ctx with match user ctx with
| Some u -> json ((db ctx).JournalByUserId u.Value) next ctx | Some u -> json ((db ctx).JournalByUserId u.Value) next ctx
| None -> Error.notFound next ctx | None -> Error.notFound next ctx

View File

@ -22,4 +22,8 @@
<PackageReference Update="FSharp.Core" Version="4.5.2" /> <PackageReference Update="FSharp.Core" Version="4.5.2" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
</Project> </Project>

View File

@ -1,36 +1,50 @@
namespace MyPrayerJournal.Api namespace MyPrayerJournal.Api
open System
open Microsoft.AspNetCore
open Microsoft.AspNetCore.Builder open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.Configuration
open Microsoft.Extensions.Logging
/// Configuration functions for the application /// Configuration functions for the application
module Configure = module Configure =
open Microsoft.AspNetCore.Authentication.JwtBearer
open Microsoft.AspNetCore.Server.Kestrel.Core
open Microsoft.Extensions.Configuration
open Microsoft.Extensions.DependencyInjection open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Logging
open Giraffe open Giraffe
open Giraffe.TokenRouter open Giraffe.TokenRouter
open MyPrayerJournal
/// Set up the configuration for the app /// Set up the configuration for the app
let configuration (ctx : WebHostBuilderContext) (cfg : IConfigurationBuilder) = let configuration (ctx : WebHostBuilderContext) (cfg : IConfigurationBuilder) =
cfg.SetBasePath(ctx.HostingEnvironment.ContentRootPath) cfg.SetBasePath(ctx.HostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json", optional = true, reloadOnChange = true) .AddJsonFile("appsettings.json", optional = true, reloadOnChange = true)
.AddJsonFile(sprintf "appsettings.%s.json" ctx.HostingEnvironment.EnvironmentName, optional = true) .AddJsonFile(sprintf "appsettings.%s.json" ctx.HostingEnvironment.EnvironmentName)
.AddEnvironmentVariables() .AddEnvironmentVariables()
|> ignore |> ignore
/// Configure Kestrel from appsettings.json
let kestrel (ctx : WebHostBuilderContext) (opts : KestrelServerOptions) =
(ctx.Configuration.GetSection >> opts.Configure >> ignore) "Kestrel"
/// Configure dependency injection /// Configure dependency injection
let services (sc : IServiceCollection) = let services (sc : IServiceCollection) =
sc.AddAuthentication() sc.AddGiraffe () |> ignore
.AddJwtBearer("Auth0", // mad props to Andrea Chiarelli @ https://auth0.com/blog/securing-asp-dot-net-core-2-applications-with-jwts/
fun opt -> use sp = sc.BuildServiceProvider()
opt.Audience <- "") let cfg = sp.GetRequiredService<IConfiguration>().GetSection "Auth0"
sc.AddAuthentication(
fun opts ->
opts.DefaultAuthenticateScheme <- JwtBearerDefaults.AuthenticationScheme
opts.DefaultChallengeScheme <- JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer (
fun opts ->
opts.Authority <- sprintf "https://%s/" cfg.["Domain"]
opts.Audience <- cfg.["Audience"]
opts.TokenValidationParameters.ValidateAudience <- false)
|> ignore
sc.AddAuthorization (fun opts -> opts.AddPolicy ("LoggedOn", fun p -> p.RequireClaim "sub" |> ignore))
|> ignore |> ignore
()
/// Routes for the available URLs within myPrayerJournal /// Routes for the available URLs within myPrayerJournal
let webApp = let webApp =
@ -82,6 +96,7 @@ module Configure =
module Program = module Program =
open System
open System.IO open System.IO
let exitCode = 0 let exitCode = 0
@ -89,10 +104,10 @@ module Program =
let CreateWebHostBuilder args = let CreateWebHostBuilder args =
let contentRoot = Directory.GetCurrentDirectory () let contentRoot = Directory.GetCurrentDirectory ()
WebHostBuilder() WebHostBuilder()
.UseKestrel()
.UseContentRoot(contentRoot) .UseContentRoot(contentRoot)
.ConfigureAppConfiguration(Configure.configuration)
.UseKestrel(Configure.kestrel)
.UseWebRoot(Path.Combine (contentRoot, "wwwroot")) .UseWebRoot(Path.Combine (contentRoot, "wwwroot"))
.ConfigureAppConfiguration(Action<WebHostBuilderContext, IConfigurationBuilder> Configure.configuration)
.ConfigureServices(Configure.services) .ConfigureServices(Configure.services)
.ConfigureLogging(Configure.logging) .ConfigureLogging(Configure.logging)
.Configure(Action<IApplicationBuilder> Configure.application) .Configure(Action<IApplicationBuilder> Configure.application)

View File

@ -0,0 +1,9 @@
{
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://localhost:3000"
}
}
}
}

View File

@ -4,8 +4,8 @@ var path = require('path')
module.exports = { module.exports = {
build: { build: {
env: require('./prod.env'), env: require('./prod.env'),
index: path.resolve(__dirname, '../../public/index.html'), index: path.resolve(__dirname, '../../api/MyPrayerJournal.Api/wwwroot/index.html'),
assetsRoot: path.resolve(__dirname, '../../public'), assetsRoot: path.resolve(__dirname, '../../api/MyPrayerJournal.Api/wwwroot'),
assetsSubDirectory: 'static', assetsSubDirectory: 'static',
assetsPublicPath: '/', assetsPublicPath: '/',
productionSourceMap: true, productionSourceMap: true,

View File

@ -1,6 +1,6 @@
{ {
"name": "my-prayer-journal", "name": "my-prayer-journal",
"version": "0.9.6", "version": "0.9.7",
"description": "myPrayerJournal - Front End", "description": "myPrayerJournal - Front End",
"author": "Daniel J. Summers <daniel@bitbadger.solutions>", "author": "Daniel J. Summers <daniel@bitbadger.solutions>",
"private": true, "private": true,
@ -12,8 +12,8 @@
"e2e": "node test/e2e/runner.js", "e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e", "test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs", "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs",
"apistart": "cd .. && go build -o mpj-api.exe && mpj-api.exe", "apistart": "cd ../api/MyPrayerJournal.Api && dotnet run",
"vue": "node build/build.js prod && cd .. && go build -o mpj-api.exe && mpj-api.exe" "vue": "node build/build.js prod && cd ../api/MyPrayerJournal.Api && dotnet run"
}, },
"dependencies": { "dependencies": {
"auth0-js": "^9.3.3", "auth0-js": "^9.3.3",