3 * _| || |_/ ___| ___ _ __ _ __ ___ | |
4 * |_ .. _\___ \ / _ \ '_ \| '_ \ / _ \| |
5 * |_ _|___) | __/ |_) | |_) | (_) |_|
6 * |_||_| |____/ \___| .__/| .__/ \___/(_)
13 * Copyright (C) The #Seppo contributors. All rights reserved.
15 * This program is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
33 * delete the file Auth.fn
36 let fn = "app/etc/passwd.s"
37 type uid
= Uid
of string
38 type bcrypt
= Bcrypt
of string
41 let is_setup = File.exists
43 let to_file fn (Uid uid
, pwd
) =
44 Logr.debug
(fun m
-> m
"to_file '%s' ..." uid
);
45 let h = Bcrypt.hash pwd
|> Bcrypt.string_of_hash
in
46 fn |> File.out_channel_replace
(fun oc
->
47 Csexp.(List
[ Atom
"uid"; Atom uid
; Atom
"bcrypt"; Atom
h ] |> to_channel oc
);
51 fn |> File.in_channel
(fun ic
->
54 | Ok List
[ Atom
"uid"; Atom uid
; Atom
"bcrypt"; Atom hash
] -> Ok
(Uid uid
, Bcrypt hash
)
56 | _
-> Error
"invalid credential store" )
58 let uid_from_file fn =
59 Logr.debug
(fun m
-> m
"Auth.uid_from_file");
61 match from_file fn with
62 | Ok
(uid
, _
) -> Ok uid
65 | Sys_error e
-> Error e
67 (* https://opam.ocaml.org/packages/safepass/ *)
68 let chk (Uid uid'
, Bcrypt hash'
) (Uid uid
, pwd
) =
69 Logr.debug
(fun m
-> m
"Auth.chk '%s' '%s'" uid
"***");
71 |> Bcrypt.hash_of_string
73 && String.equal uid' uid
75 else Error
"invalid username or password"
77 let chk_file fn cred
=
78 match from_file fn with
82 (* https://opam.ocaml.org/packages/safepass/ *)
83 let verify cred
(uid'
, hash'
) =
84 let level = Logs.Debug
85 and error
= Http.s403'
in
87 |> Result.map_error
(Http.err500 ~error ~
level "Auth.verify")
89 let verify_file fn cred
=
90 let level = Logs.Debug
91 and error
= Http.s403'
in
93 |> Result.map_error
(Http.err500 ~error ~
level "Auth.verify_file")