Authentication, take 2; take 3 forthcoming...
*cue sad trombone*
This commit is contained in:
parent
c0237e1433
commit
d3a80b9ceb
@ -8,6 +8,7 @@ open Microsoft.Extensions.Configuration
|
|||||||
open Microsoft.Extensions.DependencyInjection
|
open Microsoft.Extensions.DependencyInjection
|
||||||
open Microsoft.Extensions.Logging
|
open Microsoft.Extensions.Logging
|
||||||
open Microsoft.Extensions.Options
|
open Microsoft.Extensions.Options
|
||||||
|
open RethinkDB.DistributedCache
|
||||||
open System
|
open System
|
||||||
open System.IO
|
open System.IO
|
||||||
|
|
||||||
@ -28,46 +29,45 @@ type Startup(env : IHostingEnvironment) =
|
|||||||
|
|
||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
member this.ConfigureServices (services : IServiceCollection) =
|
member this.ConfigureServices (services : IServiceCollection) =
|
||||||
ignore <| services.AddOptions ()
|
services.AddOptions () |> ignore
|
||||||
ignore <| services.Configure<AppConfig>(this.Configuration.GetSection("MyPrayerJournal"))
|
services.Configure<AppConfig> (this.Configuration.GetSection "MyPrayerJournal") |> ignore
|
||||||
ignore <| services.AddLocalization (fun options -> options.ResourcesPath <- "Resources")
|
services.AddLocalization (fun opt -> opt.ResourcesPath <- "Resources") |> ignore
|
||||||
ignore <| services.AddMvc ()
|
services.AddMvc () |> ignore
|
||||||
ignore <| services.AddDistributedMemoryCache ()
|
//ignore <| services.AddDistributedMemoryCache ()
|
||||||
// RethinkDB connection
|
// RethinkDB connection
|
||||||
async {
|
async {
|
||||||
let cfg = services.BuildServiceProvider().GetService<IOptions<AppConfig>>().Value
|
let cfg = services.BuildServiceProvider().GetService<IOptions<AppConfig>>().Value
|
||||||
let! conn = DataConfig.Connect cfg.DataConfig
|
let! conn = DataConfig.Connect cfg.DataConfig
|
||||||
do! conn.EstablishEnvironment cfg
|
do! conn.EstablishEnvironment cfg
|
||||||
ignore <| services.AddSingleton conn
|
services.AddSingleton conn |> ignore
|
||||||
//ignore <| services.AddDistributedRethinkDBCache (fun options ->
|
services.AddDistributedRethinkDBCache (fun options ->
|
||||||
// options.Connection <- conn
|
options.Database <- match cfg.DataConfig.Database with null -> "" | db -> db
|
||||||
// options.Database <- match cfg.DataConfig.Database with null -> "" | db -> db
|
options.TableName <- "Session") |> ignore
|
||||||
// options.TableName <- "Session")
|
services.AddSession () |> ignore
|
||||||
ignore <| services.AddSession ()
|
|
||||||
} |> Async.RunSynchronously
|
} |> Async.RunSynchronously
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
member this.Configure (app : IApplicationBuilder, env : IHostingEnvironment, loggerFactory : ILoggerFactory) =
|
member this.Configure (app : IApplicationBuilder, env : IHostingEnvironment, loggerFactory : ILoggerFactory) =
|
||||||
ignore <| loggerFactory.AddConsole(this.Configuration.GetSection "Logging")
|
loggerFactory.AddConsole(this.Configuration.GetSection "Logging") |> ignore
|
||||||
ignore <| loggerFactory.AddDebug ()
|
loggerFactory.AddDebug () |> ignore
|
||||||
|
|
||||||
match env.IsDevelopment () with
|
match env.IsDevelopment () with
|
||||||
| true -> ignore <| app.UseDeveloperExceptionPage ()
|
| true -> app.UseDeveloperExceptionPage () |> ignore
|
||||||
ignore <| app.UseBrowserLink ()
|
app.UseBrowserLink () |> ignore
|
||||||
| _ -> ignore <| app.UseExceptionHandler("/error")
|
| _ -> app.UseExceptionHandler "/error" |> ignore
|
||||||
|
|
||||||
ignore <| app.UseStaticFiles ()
|
app.UseStaticFiles () |> ignore
|
||||||
|
|
||||||
ignore <| app.UseCookieAuthentication(
|
app.UseCookieAuthentication(
|
||||||
CookieAuthenticationOptions(
|
CookieAuthenticationOptions(
|
||||||
AuthenticationScheme = Keys.Authentication,
|
AuthenticationScheme = Keys.Authentication,
|
||||||
LoginPath = PathString("/user/log-on"),
|
LoginPath = PathString "/user/log-on",
|
||||||
AutomaticAuthenticate = true,
|
AutomaticAuthenticate = true,
|
||||||
AutomaticChallenge = true,
|
AutomaticChallenge = true,
|
||||||
ExpireTimeSpan = TimeSpan(2, 0, 0),
|
ExpireTimeSpan = TimeSpan (2, 0, 0),
|
||||||
SlidingExpiration = true))
|
SlidingExpiration = true)) |> ignore
|
||||||
ignore <| app.UseMvc(fun routes ->
|
app.UseMvc(fun routes ->
|
||||||
ignore <| routes.MapRoute(name = "default", template = "{controller=Home}/{action=Index}/{id?}"))
|
routes.MapRoute(name = "default", template = "{controller=Home}/{action=Index}/{id?}") |> ignore) |> ignore
|
||||||
|
|
||||||
/// Default to Development environment
|
/// Default to Development environment
|
||||||
let defaults = seq { yield WebHostDefaults.EnvironmentKey, "Development" }
|
let defaults = seq { yield WebHostDefaults.EnvironmentKey, "Development" }
|
||||||
@ -81,12 +81,12 @@ let main argv =
|
|||||||
.AddEnvironmentVariables("ASPNETCORE_")
|
.AddEnvironmentVariables("ASPNETCORE_")
|
||||||
.AddCommandLine(argv)
|
.AddCommandLine(argv)
|
||||||
.Build()
|
.Build()
|
||||||
|
use host =
|
||||||
WebHostBuilder()
|
WebHostBuilder()
|
||||||
.UseConfiguration(cfg)
|
.UseConfiguration(cfg)
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseStartup<Startup>()
|
.UseStartup<Startup>()
|
||||||
.Build()
|
.Build()
|
||||||
.Run()
|
host.Run()
|
||||||
0
|
0
|
@ -2,20 +2,23 @@ namespace MyPrayerJournal.Controllers
|
|||||||
|
|
||||||
open Microsoft.AspNetCore.Authorization
|
open Microsoft.AspNetCore.Authorization
|
||||||
open Microsoft.AspNetCore.Mvc
|
open Microsoft.AspNetCore.Mvc
|
||||||
|
open Microsoft.Extensions.Logging
|
||||||
open MyPrayerJournal
|
open MyPrayerJournal
|
||||||
open RethinkDb.Driver.Net
|
open RethinkDb.Driver.Net
|
||||||
|
|
||||||
/// Home controller
|
/// Home controller
|
||||||
[<Authorize>]
|
[<Authorize>]
|
||||||
[<Route("")>]
|
[<Route("")>]
|
||||||
type HomeController(data : IConnection) =
|
type HomeController(data : IConnection, logger : ILogger<HomeController>) =
|
||||||
inherit ApplicationController(data)
|
inherit ApplicationController(data)
|
||||||
|
|
||||||
[<AllowAnonymous>]
|
[<AllowAnonymous>]
|
||||||
[<HttpGet("")>]
|
[<HttpGet("")>]
|
||||||
member this.Index() =
|
member this.Index() =
|
||||||
|
logger.LogDebug(Newtonsoft.Json.JsonConvert.SerializeObject this.HttpContext.User)
|
||||||
async {
|
async {
|
||||||
match this.HttpContext.User with
|
match this.HttpContext.User with
|
||||||
| :? AppUser as user -> return this.View "Dashboard" :> IActionResult
|
| :? AppUser as user -> return this.View "Dashboard" :> IActionResult
|
||||||
| _ -> return upcast this.View ()
|
| _ -> return upcast this.View ()
|
||||||
} |> Async.StartAsTask
|
}
|
||||||
|
|> Async.StartAsTask
|
||||||
|
@ -25,7 +25,7 @@ type UserController(data : IConnection, cfg : IOptions<AppConfig>) =
|
|||||||
async {
|
async {
|
||||||
let! user = data.LogOnUser form.Email (User.HashPassword form.Password cfg.Value.PasswordSaltBytes)
|
let! user = data.LogOnUser form.Email (User.HashPassword form.Password cfg.Value.PasswordSaltBytes)
|
||||||
match user with
|
match user with
|
||||||
| Some usr -> do! this.HttpContext.Authentication.SignInAsync(Keys.Authentication, AppUser(user))
|
| Some usr -> do! this.HttpContext.Authentication.SignInAsync (Keys.Authentication, AppUser user)
|
||||||
// TODO: welcome message
|
// TODO: welcome message
|
||||||
(* this.Session.[Keys.User] <- usr
|
(* this.Session.[Keys.User] <- usr
|
||||||
{ UserMessage.Empty with Level = Level.Info
|
{ UserMessage.Empty with Level = Level.Info
|
||||||
@ -37,13 +37,13 @@ type UserController(data : IConnection, cfg : IOptions<AppConfig>) =
|
|||||||
|> model.AddMessage
|
|> model.AddMessage
|
||||||
return this.Redirect "/user/log-on" model *)
|
return this.Redirect "/user/log-on" model *)
|
||||||
return upcast this.RedirectToAction "ShowLogOn"
|
return upcast this.RedirectToAction "ShowLogOn"
|
||||||
//return this.View()
|
}
|
||||||
} |> Async.StartAsTask
|
|> Async.StartAsTask
|
||||||
|
|
||||||
[<HttpGet("log-off")>]
|
[<HttpGet("log-off")>]
|
||||||
member this.LogOff () =
|
member this.LogOff () =
|
||||||
async {
|
async {
|
||||||
do! this.HttpContext.Authentication.SignOutAsync(Keys.Authentication)
|
do! this.HttpContext.Authentication.SignOutAsync Keys.Authentication
|
||||||
// TODO: goodbye message
|
// TODO: goodbye message
|
||||||
return this.LocalRedirect "/"
|
return this.LocalRedirect "/"
|
||||||
} |> Async.StartAsTask
|
} |> Async.StartAsTask
|
@ -29,7 +29,7 @@ type IConnection with
|
|||||||
.Filter(ReqlFunction1(fun usr -> upcast usr.["PasswordHash"].Eq(passwordHash)))
|
.Filter(ReqlFunction1(fun usr -> upcast usr.["PasswordHash"].Eq(passwordHash)))
|
||||||
.RunResultAsync<User list>(this)
|
.RunResultAsync<User list>(this)
|
||||||
return user |> List.tryHead
|
return user |> List.tryHead
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set up the environment for MyPrayerJournal
|
/// Set up the environment for MyPrayerJournal
|
||||||
member this.EstablishEnvironment (cfg : AppConfig) =
|
member this.EstablishEnvironment (cfg : AppConfig) =
|
||||||
@ -50,7 +50,7 @@ type IConnection with
|
|||||||
| _ -> logStepStart " Database not found - creating..."
|
| _ -> logStepStart " Database not found - creating..."
|
||||||
do! r.DbCreate("MyPrayerJournal").RunResultAsync(this)
|
do! r.DbCreate("MyPrayerJournal").RunResultAsync(this)
|
||||||
logStepEnd ()
|
logStepEnd ()
|
||||||
}
|
}
|
||||||
/// Ensure all tables exit
|
/// Ensure all tables exit
|
||||||
let checkTables () =
|
let checkTables () =
|
||||||
async {
|
async {
|
||||||
@ -63,7 +63,7 @@ type IConnection with
|
|||||||
logStepStart <| sprintf " %s table not found - creating..." tbl
|
logStepStart <| sprintf " %s table not found - creating..." tbl
|
||||||
do! db().TableCreate(tbl).RunResultAsync(this)
|
do! db().TableCreate(tbl).RunResultAsync(this)
|
||||||
logStepEnd()
|
logStepEnd()
|
||||||
})
|
})
|
||||||
|> List.iter Async.RunSynchronously
|
|> List.iter Async.RunSynchronously
|
||||||
// Seed the user table if it is empty
|
// Seed the user table if it is empty
|
||||||
let! userCount = db().Table(DataTable.User).Count().RunResultAsync<int64>(this)
|
let! userCount = db().Table(DataTable.User).Count().RunResultAsync<int64>(this)
|
||||||
@ -75,7 +75,8 @@ type IConnection with
|
|||||||
Email = "test@example.com"
|
Email = "test@example.com"
|
||||||
PasswordHash = User.HashPassword "password" cfg.PasswordSaltBytes
|
PasswordHash = User.HashPassword "password" cfg.PasswordSaltBytes
|
||||||
Name = "Default User"
|
Name = "Default User"
|
||||||
TimeZone = "America/Chicago" }).RunResultAsync(this)
|
TimeZone = "America/Chicago"
|
||||||
|
}).RunResultAsync(this)
|
||||||
logStepEnd ()
|
logStepEnd ()
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
}
|
}
|
||||||
@ -95,11 +96,11 @@ type IConnection with
|
|||||||
| _ -> logStepStart <| sprintf " %s.Email index not found - creating..." DataTable.User
|
| _ -> logStepStart <| sprintf " %s.Email index not found - creating..." DataTable.User
|
||||||
do! db().Table(DataTable.User).IndexCreate("Email").RunResultAsync(this)
|
do! db().Table(DataTable.User).IndexCreate("Email").RunResultAsync(this)
|
||||||
logStepEnd ()
|
logStepEnd ()
|
||||||
}
|
}
|
||||||
async {
|
async {
|
||||||
logStep "Database checks starting"
|
logStep "Database checks starting"
|
||||||
do! checkDatabase ()
|
do! checkDatabase ()
|
||||||
do! checkTables ()
|
do! checkTables ()
|
||||||
do! checkIndexes ()
|
do! checkIndexes ()
|
||||||
logStep "Database checks complete"
|
logStep "Database checks complete"
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,6 @@
|
|||||||
<script src="~/js/site.min.js" asp-append-version="true"></script>
|
<script src="~/js/site.min.js" asp-append-version="true"></script>
|
||||||
</environment>
|
</environment>
|
||||||
|
|
||||||
@RenderSection("scripts", required: false)
|
@RenderSection("Scripts", required: false)
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -28,4 +28,13 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@section Scripts
|
||||||
|
{
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* <![CDATA[ */
|
||||||
|
$(document).ready(function () { $("#Email").focus() })
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
|
}
|
@ -37,6 +37,7 @@
|
|||||||
},
|
},
|
||||||
"Newtonsoft.Json": "9.0.1",
|
"Newtonsoft.Json": "9.0.1",
|
||||||
"NodaTime": "2.0.0-alpha20160729",
|
"NodaTime": "2.0.0-alpha20160729",
|
||||||
|
"RethinkDB.DistributedCache": "0.9.0-alpha01",
|
||||||
"RethinkDb.Driver": "2.3.15"
|
"RethinkDb.Driver": "2.3.15"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user