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