Add user created and last seen on (#19)
- Updated view models / interfaces per F# naming guidelines
This commit is contained in:
@@ -17,22 +17,18 @@ open MyWebLog
|
||||
open MyWebLog.ViewModels
|
||||
|
||||
// GET /user/log-on
|
||||
let logOn returnUrl : HttpHandler = fun next ctx -> task {
|
||||
let logOn returnUrl : HttpHandler = fun next ctx ->
|
||||
let returnTo =
|
||||
match returnUrl with
|
||||
| Some _ -> returnUrl
|
||||
| None ->
|
||||
match ctx.Request.Query.ContainsKey "returnUrl" with
|
||||
| true -> Some ctx.Request.Query["returnUrl"].[0]
|
||||
| false -> None
|
||||
return!
|
||||
Hash.FromAnonymousObject {|
|
||||
page_title = "Log On"
|
||||
csrf = ctx.CsrfTokenSet
|
||||
model = { LogOnModel.empty with returnTo = returnTo }
|
||||
|}
|
||||
|> viewForTheme "admin" "log-on" next ctx
|
||||
}
|
||||
| None -> if ctx.Request.Query.ContainsKey "returnUrl" then Some ctx.Request.Query["returnUrl"].[0] else None
|
||||
Hash.FromAnonymousObject {|
|
||||
page_title = "Log On"
|
||||
csrf = ctx.CsrfTokenSet
|
||||
model = { LogOnModel.empty with ReturnTo = returnTo }
|
||||
|}
|
||||
|> viewForTheme "admin" "log-on" next ctx
|
||||
|
||||
|
||||
open System.Security.Claims
|
||||
open Microsoft.AspNetCore.Authentication
|
||||
@@ -41,8 +37,9 @@ open Microsoft.AspNetCore.Authentication.Cookies
|
||||
// POST /user/log-on
|
||||
let doLogOn : HttpHandler = fun next ctx -> task {
|
||||
let! model = ctx.BindFormAsync<LogOnModel> ()
|
||||
match! ctx.Data.WebLogUser.findByEmail model.emailAddress ctx.WebLog.id with
|
||||
| Some user when user.passwordHash = hashedPassword model.password user.userName user.salt ->
|
||||
let data = ctx.Data
|
||||
match! data.WebLogUser.FindByEmail model.EmailAddress ctx.WebLog.id with
|
||||
| Some user when user.passwordHash = hashedPassword model.Password user.userName user.salt ->
|
||||
let claims = seq {
|
||||
Claim (ClaimTypes.NameIdentifier, WebLogUserId.toString user.id)
|
||||
Claim (ClaimTypes.Name, $"{user.firstName} {user.lastName}")
|
||||
@@ -53,34 +50,35 @@ let doLogOn : HttpHandler = fun next ctx -> task {
|
||||
|
||||
do! ctx.SignInAsync (identity.AuthenticationType, ClaimsPrincipal identity,
|
||||
AuthenticationProperties (IssuedUtc = DateTimeOffset.UtcNow))
|
||||
do! data.WebLogUser.SetLastSeen user.id user.webLogId
|
||||
do! addMessage ctx
|
||||
{ UserMessage.success with message = $"Logged on successfully | Welcome to {ctx.WebLog.name}!" }
|
||||
{ UserMessage.success with Message = $"Logged on successfully | Welcome to {ctx.WebLog.name}!" }
|
||||
return!
|
||||
match model.returnTo with
|
||||
match model.ReturnTo with
|
||||
| Some url -> redirectTo false url next ctx
|
||||
| None -> redirectToGet "admin/dashboard" next ctx
|
||||
| _ ->
|
||||
do! addMessage ctx { UserMessage.error with message = "Log on attempt unsuccessful" }
|
||||
return! logOn model.returnTo next ctx
|
||||
do! addMessage ctx { UserMessage.error with Message = "Log on attempt unsuccessful" }
|
||||
return! logOn model.ReturnTo next ctx
|
||||
}
|
||||
|
||||
// GET /user/log-off
|
||||
let logOff : HttpHandler = fun next ctx -> task {
|
||||
do! ctx.SignOutAsync CookieAuthenticationDefaults.AuthenticationScheme
|
||||
do! addMessage ctx { UserMessage.info with message = "Log off successful" }
|
||||
do! addMessage ctx { UserMessage.info with Message = "Log off successful" }
|
||||
return! redirectToGet "" next ctx
|
||||
}
|
||||
|
||||
/// Display the user edit page, with information possibly filled in
|
||||
let private showEdit (hash : Hash) : HttpHandler = fun next ctx -> task {
|
||||
hash.Add ("page_title", "Edit Your Information")
|
||||
hash.Add ("csrf", ctx.CsrfTokenSet)
|
||||
return! viewForTheme "admin" "user-edit" next ctx hash
|
||||
}
|
||||
let private showEdit (hash : Hash) : HttpHandler = fun next ctx ->
|
||||
addToHash "page_title" "Edit Your Information" hash
|
||||
|> addToHash "csrf" ctx.CsrfTokenSet
|
||||
|> viewForTheme "admin" "user-edit" next ctx
|
||||
|
||||
|
||||
// GET /admin/user/edit
|
||||
let edit : HttpHandler = requireAccess Author >=> fun next ctx -> task {
|
||||
match! ctx.Data.WebLogUser.findById ctx.UserId ctx.WebLog.id with
|
||||
match! ctx.Data.WebLogUser.FindById ctx.UserId ctx.WebLog.id with
|
||||
| Some user -> return! showEdit (Hash.FromAnonymousObject {| model = EditUserModel.fromUser user |}) next ctx
|
||||
| None -> return! Error.notFound next ctx
|
||||
}
|
||||
@@ -88,32 +86,32 @@ let edit : HttpHandler = requireAccess Author >=> fun next ctx -> task {
|
||||
// POST /admin/user/save
|
||||
let save : HttpHandler = requireAccess Author >=> fun next ctx -> task {
|
||||
let! model = ctx.BindFormAsync<EditUserModel> ()
|
||||
if model.newPassword = model.newPasswordConfirm then
|
||||
if model.NewPassword = model.NewPasswordConfirm then
|
||||
let data = ctx.Data
|
||||
match! data.WebLogUser.findById ctx.UserId ctx.WebLog.id with
|
||||
match! data.WebLogUser.FindById ctx.UserId ctx.WebLog.id with
|
||||
| Some user ->
|
||||
let pw, salt =
|
||||
if model.newPassword = "" then
|
||||
if model.NewPassword = "" then
|
||||
user.passwordHash, user.salt
|
||||
else
|
||||
let newSalt = Guid.NewGuid ()
|
||||
hashedPassword model.newPassword user.userName newSalt, newSalt
|
||||
hashedPassword model.NewPassword user.userName newSalt, newSalt
|
||||
let user =
|
||||
{ user with
|
||||
firstName = model.firstName
|
||||
lastName = model.lastName
|
||||
preferredName = model.preferredName
|
||||
firstName = model.FirstName
|
||||
lastName = model.LastName
|
||||
preferredName = model.PreferredName
|
||||
passwordHash = pw
|
||||
salt = salt
|
||||
}
|
||||
do! data.WebLogUser.update user
|
||||
let pwMsg = if model.newPassword = "" then "" else " and updated your password"
|
||||
do! addMessage ctx { UserMessage.success with message = $"Saved your information{pwMsg} successfully" }
|
||||
do! data.WebLogUser.Update user
|
||||
let pwMsg = if model.NewPassword = "" then "" else " and updated your password"
|
||||
do! addMessage ctx { UserMessage.success with Message = $"Saved your information{pwMsg} successfully" }
|
||||
return! redirectToGet "admin/user/edit" next ctx
|
||||
| None -> return! Error.notFound next ctx
|
||||
else
|
||||
do! addMessage ctx { UserMessage.error with message = "Passwords did not match; no updates made" }
|
||||
do! addMessage ctx { UserMessage.error with Message = "Passwords did not match; no updates made" }
|
||||
return! showEdit (Hash.FromAnonymousObject {|
|
||||
model = { model with newPassword = ""; newPasswordConfirm = "" }
|
||||
model = { model with NewPassword = ""; NewPasswordConfirm = "" }
|
||||
|}) next ctx
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user