cli/insert: add --try-decrypt=(true|false)

Enable override of the index.try_decrypt setting on a per-message
basis when invoking "notmuch insert".

We also update the documentation and tab completion, and add more tests.
This commit is contained in:
Daniel Kahn Gillmor 2017-10-20 22:25:47 -04:00 committed by David Bremner
parent 35456d4b0c
commit c5356b9ed5
4 changed files with 86 additions and 4 deletions

View file

@ -287,12 +287,16 @@ _notmuch_insert()
sed "s|^$path/||" | grep -v "\(^\|/\)\(cur\|new\|tmp\)$" ) ) sed "s|^$path/||" | grep -v "\(^\|/\)\(cur\|new\|tmp\)$" ) )
return return
;; ;;
--try-decrypt)
COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
return
;;
esac esac
! $split && ! $split &&
case "${cur}" in case "${cur}" in
--*) --*)
local options="--create-folder --folder= --keep --no-hooks ${_notmuch_shared_options}" local options="--create-folder --folder= --keep --no-hooks --try-decrypt= ${_notmuch_shared_options}"
compopt -o nospace compopt -o nospace
COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
return return

View file

@ -50,6 +50,20 @@ Supported options for **insert** include
``--no-hooks`` ``--no-hooks``
Prevent hooks from being run. Prevent hooks from being run.
``--try-decrypt=(true|false)``
If true and the message is encrypted, try to decrypt the
message while indexing. If decryption is successful, index
the cleartext itself. Either way, the message is always
stored to disk in its original form (ciphertext). Be aware
that the index is likely sufficient to reconstruct the
cleartext of the message itself, so please ensure that the
notmuch message index is adequately protected. DO NOT USE
``--try-decrypt=true`` without considering the security of
your index.
See also ``index.try_decrypt`` in **notmuch-config(1)**.
EXIT STATUS EXIT STATUS
=========== ===========

View file

@ -379,12 +379,13 @@ FAIL:
*/ */
static notmuch_status_t static notmuch_status_t
add_file (notmuch_database_t *notmuch, const char *path, tag_op_list_t *tag_ops, add_file (notmuch_database_t *notmuch, const char *path, tag_op_list_t *tag_ops,
bool synchronize_flags, bool keep) bool synchronize_flags, bool keep,
notmuch_indexopts_t *indexopts)
{ {
notmuch_message_t *message; notmuch_message_t *message;
notmuch_status_t status; notmuch_status_t status;
status = notmuch_database_index_file (notmuch, path, NULL, &message); status = notmuch_database_index_file (notmuch, path, indexopts, &message);
if (status == NOTMUCH_STATUS_SUCCESS) { if (status == NOTMUCH_STATUS_SUCCESS) {
status = tag_op_list_apply (message, tag_ops, 0); status = tag_op_list_apply (message, tag_ops, 0);
if (status) { if (status) {
@ -467,6 +468,7 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])
{ .opt_bool = &create_folder, .name = "create-folder" }, { .opt_bool = &create_folder, .name = "create-folder" },
{ .opt_bool = &keep, .name = "keep" }, { .opt_bool = &keep, .name = "keep" },
{ .opt_bool = &no_hooks, .name = "no-hooks" }, { .opt_bool = &no_hooks, .name = "no-hooks" },
{ .opt_inherit = notmuch_shared_indexing_options },
{ .opt_inherit = notmuch_shared_options }, { .opt_inherit = notmuch_shared_options },
{ } { }
}; };
@ -545,9 +547,15 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])
notmuch_exit_if_unmatched_db_uuid (notmuch); notmuch_exit_if_unmatched_db_uuid (notmuch);
status = notmuch_process_shared_indexing_options (notmuch, config);
if (status != NOTMUCH_STATUS_SUCCESS) {
fprintf (stderr, "Error: Failed to process index options. (%s)\n",
notmuch_status_to_string (status));
return EXIT_FAILURE;
}
/* Index the message. */ /* Index the message. */
status = add_file (notmuch, newpath, tag_ops, synchronize_flags, keep); status = add_file (notmuch, newpath, tag_ops, synchronize_flags, keep, indexing_cli_choices.opts);
/* Commit changes. */ /* Commit changes. */
close_status = notmuch_database_destroy (notmuch); close_status = notmuch_database_destroy (notmuch);

View file

@ -48,4 +48,60 @@ test_expect_equal \
"$output" \ "$output" \
"$expected" "$expected"
test_begin_subtest "message should go away after deletion"
# cache the message in an env var and remove it:
fname=$(notmuch search --output=files wumpus)
contents="$(notmuch show --format=raw wumpus)"
rm -f "$fname"
notmuch new
output=$(notmuch search wumpus)
expected=''
test_expect_equal \
"$output" \
"$expected"
# try reinserting it without decryption, should stay the same:
test_begin_subtest "message cleartext not present after insert"
notmuch insert --folder=sent <<<"$contents"
output=$(notmuch search wumpus)
test_expect_equal \
"$output" \
"$expected"
# try reinserting it with decryption, should appear again, but now we
# have two copies of the message:
test_begin_subtest "message cleartext is present after reinserting with --try-decrypt"
notmuch insert --folder=sent --try-decrypt <<<"$contents"
output=$(notmuch search wumpus)
expected='thread:0000000000000003 2000-01-01 [1/1(2)] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
test_expect_equal \
"$output" \
"$expected"
# remove all copies
test_begin_subtest "delete all copies of the message"
mid="$(notmuch search --output=messages wumpus)"
rm -f $(notmuch search --output=files wumpus)
notmuch new
output=$(notmuch search "id:$mid")
expected=''
test_expect_equal \
"$output" \
"$expected"
# try inserting it with decryption, should appear as a single copy
# (note: i think thread id skips 4 because of duplicate message-id
# insertion, above)
test_begin_subtest "message cleartext is present with insert --try-decrypt"
notmuch insert --folder=sent --try-decrypt <<<"$contents"
output=$(notmuch search wumpus)
expected='thread:0000000000000005 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
test_expect_equal \
"$output" \
"$expected"
test_done test_done