Version 3 #40
|
@ -159,6 +159,8 @@ type OtherContact =
|
|||
|
||||
/// Visibility options for an employment profile
|
||||
type ProfileVisibility =
|
||||
/// Profile is only visible to the citizen to whom it belongs
|
||||
| Hidden
|
||||
/// Profile is only visible to authenticated users
|
||||
| Private
|
||||
/// Anonymous information is visible to public users
|
||||
|
@ -172,6 +174,7 @@ module ProfileVisibility =
|
|||
/// Parse a string into a profile visibility
|
||||
let parse viz =
|
||||
match viz with
|
||||
| "Hidden" -> Hidden
|
||||
| "Private" -> Private
|
||||
| "Anonymous" -> Anonymous
|
||||
| "Public" -> Public
|
||||
|
@ -180,6 +183,7 @@ module ProfileVisibility =
|
|||
/// Convert a profile visibility to its string representation
|
||||
let toString =
|
||||
function
|
||||
| Hidden -> "Hidden"
|
||||
| Private -> "Private"
|
||||
| Anonymous -> "Anonymous"
|
||||
| Public -> "Public"
|
||||
|
|
|
@ -209,15 +209,27 @@ let deleteHistory idx : HttpHandler = requireUser >=> validateCsrf >=> fun next
|
|||
| None -> return! notFound ctx
|
||||
}
|
||||
|
||||
// GET: /profile/[id]/view
|
||||
let view citizenId : HttpHandler = fun next ctx -> task {
|
||||
/// Get a profile for view, and enforce visibility restrictions against the current user
|
||||
let private getProfileForView citizenId ctx = task {
|
||||
let citId = CitizenId citizenId
|
||||
match! Data.findByIdForView citId with
|
||||
| Some profile ->
|
||||
let currentCitizen = tryUser ctx |> Option.map CitizenId.ofString
|
||||
if not (profile.Profile.Visibility = Public) && Option.isNone currentCitizen then
|
||||
return! Error.notAuthorized next ctx
|
||||
else
|
||||
let canView =
|
||||
match profile.Profile.Visibility, currentCitizen with
|
||||
| Private, Some _
|
||||
| Anonymous, Some _
|
||||
| Public, _ -> true
|
||||
| Hidden, Some citizenId when profile.Citizen.Id = citizenId -> true
|
||||
| _ -> false
|
||||
return if canView then Some (profile, currentCitizen) else None
|
||||
| None -> return None
|
||||
}
|
||||
|
||||
// GET: /profile/[id]/view
|
||||
let view citizenId : HttpHandler = fun next ctx -> task {
|
||||
match! getProfileForView citizenId ctx with
|
||||
| Some (profile, currentCitizen) ->
|
||||
let title = $"Employment Profile for {Citizen.name profile.Citizen}"
|
||||
return! Views.view profile currentCitizen |> render title next ctx
|
||||
| None -> return! notFound ctx
|
||||
|
@ -225,13 +237,8 @@ let view citizenId : HttpHandler = fun next ctx -> task {
|
|||
|
||||
// GET: /profile/[id]/print
|
||||
let print citizenId : HttpHandler = fun next ctx -> task {
|
||||
let citId = CitizenId citizenId
|
||||
match! Data.findByIdForView citId with
|
||||
| Some profile ->
|
||||
let currentCitizen = tryUser ctx |> Option.map CitizenId.ofString
|
||||
if not (profile.Profile.Visibility = Public) && Option.isNone currentCitizen then
|
||||
return! Error.notAuthorized next ctx
|
||||
else
|
||||
match! getProfileForView citizenId ctx with
|
||||
| Some (profile, currentCitizen) ->
|
||||
let pageTitle = $"Employment Profile for {Citizen.name profile.Citizen}"
|
||||
return! Views.print profile (Option.isNone currentCitizen) |> renderPrint pageTitle next ctx
|
||||
| None -> return! notFound ctx
|
||||
|
|
|
@ -102,6 +102,15 @@ let editGeneralInfo (m : EditProfileForm) continents isHtmx csrf =
|
|||
div [ _class "col-12" ] [
|
||||
hr []
|
||||
h4 [] [ txt "Visibility" ]
|
||||
div [ _class "form-check" ] [
|
||||
let hid = ProfileVisibility.toString Hidden
|
||||
input [ _type "radio"; _id $"{nameof m.Visibility}Hidden"; _name (nameof m.Visibility)
|
||||
_class "form-check-input"; _value hid; if m.Visibility = hid then _checked ]
|
||||
label [ _class "form-check-label"; _for $"{nameof m.Visibility}Hidden" ] [
|
||||
strong [] [ txt "Hidden" ]
|
||||
txt " – do not show my employment profile to anyone else"
|
||||
]
|
||||
]
|
||||
div [ _class "form-check" ] [
|
||||
let pvt = ProfileVisibility.toString Private
|
||||
input [ _type "radio"; _id $"{nameof m.Visibility}Private"; _name (nameof m.Visibility)
|
||||
|
|
Loading…
Reference in New Issue
Block a user