1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
let die ~op_string = Shell.die "E: refusing to %s: violates invariant" op_string
let user_is_listed_as_recipient path =
let open Storage.Secrets in
let folder_recipients = get_recipients_from_path_exn path in
let%lwt own_recipients = recipients_of_own_id () in
Lwt_list.exists_p
(fun (own_recipient : Age.recipient) -> Lwt.return @@ List.mem own_recipient folder_recipients)
own_recipients
let run_if_recipient ~op_string ~path ~f =
match%lwt user_is_listed_as_recipient path with
| false ->
let show_path p = Path.project p in
let base_folder = Path.folder_of_path path in
let%lwt () =
Lwt_io.eprintlf "E: user is not a recipient of %s. Please ask someone to add you as a recipient."
(show_path base_folder)
in
die ~op_string
| true -> f ()
let die_if_invariant_fails ~op_string path =
let open Storage.Secrets in
let full_path = path |> Path.folder_of_path |> Path.abs in
if (not (Path.is_directory full_path)) || FileUtil.ls (Path.project full_path) = [] then Lwt.return_unit
else (
let show_path p = Path.project p in
let show_name name = Storage.Secret_name.project name in
let base_folder = Path.folder_of_path path in
match%lwt user_is_listed_as_recipient path with
| false ->
let%lwt () =
Lwt_io.eprintlf "E: user is not a recipient of %s. Please ask someone to add you as a recipient."
(show_path base_folder)
in
die ~op_string
| true ->
let%lwt fails_invariant =
Lwt_list.exists_s
(fun s ->
try%lwt
let%lwt (_decrypted : string) = decrypt_exn ~silence_stderr:true s in
Lwt.return false
with _e ->
let%lwt () =
Lwt_io.eprintlf
"E: user is recipient of %s, but failed to decrypt %s. Please ask some user to refresh the whole \
folder."
(show_path base_folder) (show_name s)
in
Lwt.return true)
(get_secrets_in_folder base_folder)
in
if fails_invariant then die ~op_string else Lwt.return_unit)