Re: [PATCH 2/2] emacs: postpone/resume support

2016-10-01 Thread David Bremner
Mark Walters  writes:

> This provides preliminary support for postponing and resuming in the
> emacs frontend. On postponing it uses notmuch insert to put the
> message in the notmuch database; resume gets the raw file from notmuch
> and using the emacs function mime-to-mml reconstructs the message
> (including attachments).

I was thinking about this a bit more, in the context of your other patch
to scan for #secure, and it occured to me one option would be would be
to add a header to the draft being written with the secure (and other
relevant info). As a proof of concept I added a constant header to all
drafts [1].  An outline of the approach would be

- scan for #secure tags, error if they are not in the right place
- if found at the top of the document, extract the contents, remove the
  mml tag and put in a header like
  e.g.

  X-Notmuch-Emacs-Secure: method=pgpmime mode=sign

- on reading back, check for, remove that header, add the corresponding
  #secure tag.

It might be possible to re-use functions e.g. mml-secure-message and
mml-unsecure-message from mml-sec.el

Compared to the other approach we discussed (using message-properties to
store the data), this has the advantage of not requiring new features in
the CLI. Also, it would probably be a potential source of user error to
sync drafts between machines via some imap/rsync mechanism, without
syncing message metadata.

Our usual distaste for writing headers is that we don't want to modify
delivered mail; this seems a non-issue here to me since there is no
delivered mail. Others might disagree, of course.

[1]
diff --git a/emacs/notmuch-maildir-fcc.el b/emacs/notmuch-maildir-fcc.el
index 95e5650..412da94 100644
--- a/emacs/notmuch-maildir-fcc.el
+++ b/emacs/notmuch-maildir-fcc.el
@@ -163,6 +163,7 @@ by notmuch-mua-mail"
   "Setup message for saving. Should be called on a temporary copy.
 
 This is taken from the function message-do-fcc."
+  (message-add-header "X-Notmuch-Emacs-Draft: true")
   (message-encode-message-body)
   (save-restriction
 (message-narrow-to-headers)



signature.asc
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/2] emacs: postpone/resume support

2016-09-21 Thread David Bremner
Daniel Kahn Gillmor  writes:

>
> So this failure that bremner's reporting appears to happen only when
> combining the #secure mode with a message with attachments.  It doesn't
> happen when the draft itself is just plaintext and one of the #secure
> flags is set.  And there's no problem if there are attachments without
> the #secure flag.
>
> Bremner, can you confirm this?

Yes, that sounds about right. Although the emacs bug I reported does not
have to do with attachments per se, just the requirement that the
#secure tag is at the top of the message

>
> I also noticed that if you rearrange the text before sending so that the
> #secure flag is at the top of the message, the structure of the message
> looks weird -- in particular, there's a double layer of multipart/mixed
> just within the crypto transformation, instead of a single layer.
>
> that said, these patches are really useful to me even in their current
> form, since most of my draft messages don't deal with both crypto and
> attachments.  Is there some way to get the benefits here without the bug
> at the intersection?

We could (and I think emacs should) abort if it detects #secure anywhere
but on the first line.

d
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/2] emacs: postpone/resume support

2016-09-20 Thread Daniel Kahn Gillmor
On Sun 2016-09-11 08:05:20 -0400, David Bremner wrote:
> Mark Walters  writes:
>
>> This provides preliminary support for postponing and resuming in the
>> emacs frontend. On postponing it uses notmuch insert to put the
>> message in the notmuch database; resume gets the raw file from notmuch
>> and using the emacs function mime-to-mml reconstructs the message
>> (including attachments).
>
> I haven't really reviewed this yet, but I noticed it seems to need some
> special handling for signed/encrypted messages.
>
> I created a test message consisting of the mml tag
>
>   "#secure method=pgpmime mode=sign"
>
> (added with C-c C-m C-s) and a pdf attachment.
>
> Saving with C-x C-s created a text/plain part with the #secure tag in
> it. When I edited (and sent) the saved draft, it did not sign
> anything. This might be related to a bug/undocumented-feature of mml
> only parsing #secure tags at the top of the message.

So this failure that bremner's reporting appears to happen only when
combining the #secure mode with a message with attachments.  It doesn't
happen when the draft itself is just plaintext and one of the #secure
flags is set.  And there's no problem if there are attachments without
the #secure flag.

Bremner, can you confirm this?

I also noticed that if you rearrange the text before sending so that the
#secure flag is at the top of the message, the structure of the message
looks weird -- in particular, there's a double layer of multipart/mixed
just within the crypto transformation, instead of a single layer.

that said, these patches are really useful to me even in their current
form, since most of my draft messages don't deal with both crypto and
attachments.  Is there some way to get the benefits here without the bug
at the intersection?

   --dkg


signature.asc
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/2] emacs: postpone/resume support

2016-09-11 Thread David Bremner
David Bremner  writes:

> Actually, I just tested with
>  "#secure method=pgpmime mode=signencrypt"
> and the same thing happens, which is an even bigger footgun.
>
> this behaviour should really be fixed upstream in emacs, but we probably
> don't want block on that, so some kind of workaround seems to be needed.

I've reported the emacs bug at

 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24411

We'll have to see what upstream thinks.
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/2] emacs: postpone/resume support

2016-09-11 Thread David Bremner
Mark Walters  writes:

> This provides preliminary support for postponing and resuming in the
> emacs frontend. On postponing it uses notmuch insert to put the
> message in the notmuch database; resume gets the raw file from notmuch
> and using the emacs function mime-to-mml reconstructs the message
> (including attachments).

I haven't really reviewed this yet, but I noticed it seems to need some
special handling for signed/encrypted messages.

I created a test message consisting of the mml tag

  "#secure method=pgpmime mode=sign"

(added with C-c C-m C-s) and a pdf attachment.

Saving with C-x C-s created a text/plain part with the #secure tag in
it. When I edited (and sent) the saved draft, it did not sign
anything. This might be related to a bug/undocumented-feature of mml
only parsing #secure tags at the top of the message.

Actually, I just tested with
 "#secure method=pgpmime mode=signencrypt"
and the same thing happens, which is an even bigger footgun.

this behaviour should really be fixed upstream in emacs, but we probably
don't want block on that, so some kind of workaround seems to be needed.



1473594252.M451803P952.zancas:2,DS
Description: test message


signature.asc
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/2] emacs: postpone/resume support

2016-09-04 Thread Mark Walters
This provides preliminary support for postponing and resuming in the
emacs frontend. On postponing it uses notmuch insert to put the
message in the notmuch database; resume gets the raw file from notmuch
and using the emacs function mime-to-mml reconstructs the message
(including attachments).

Current bindings are C-x C-s to save a draft, C-c C-p to postpone a
draft (save and exit compose buffer), and e to resume a draft from
show or tree mode.

Previous drafts get tagged deleted on subsequent saves, or on the
message being sent.

Each draft gets its own message-id, and we use the namespace
draft- for draft message ids (so, at least for most people, drafts
are easily distinguisable).
---
 emacs/notmuch-message.el | 171 +++
 emacs/notmuch-mua.el |   4 ++
 emacs/notmuch-show.el|  11 +++
 emacs/notmuch-tree.el|   1 +
 4 files changed, 187 insertions(+)

diff --git a/emacs/notmuch-message.el b/emacs/notmuch-message.el
index 55e4cfe..b8d6d07 100644
--- a/emacs/notmuch-message.el
+++ b/emacs/notmuch-message.el
@@ -24,6 +24,9 @@
 (require 'message)
 (require 'notmuch-tag)
 (require 'notmuch-mua)
+(require 'notmuch-maildir-fcc)
+
+(declare-function notmuch-show-get-message-id "notmuch-show" ( bare))
 
 (defcustom notmuch-message-replied-tags '("+replied")
   "List of tag changes to apply to a message when it has been replied to.
@@ -38,6 +41,49 @@ the \"inbox\" and \"todo\" tags, you would set:
   :type '(repeat string)
   :group 'notmuch-send)
 
+(defcustom notmuch-message-draft-tags '("+draft")
+  "List of tags changes to apply to a draft message when it is saved in the 
database.
+
+Tags starting with \"+\" (or not starting with either \"+\" or
+\"-\") in the list will be added, and tags starting with \"-\"
+will be removed from the message being stored.
+
+For example, if you wanted to give the message a \"draft\" tag
+but not the (normally added by default) \"inbox\" tag, you would
+set:
+(\"+draft\" \"-inbox\")"
+  :type '(repeat string)
+  :group 'notmuch-send)
+
+(defcustom notmuch-message-draft-folder "drafts"
+  "Folder to save draft messages in.
+
+This should be specified relative to the root of the notmuch
+database. It will be created if necessary."
+  :type 'string
+  :group 'notmuch-send)
+
+(defcustom notmuch-message-quoted-tags '("secure")
+  "Mml tags to quote.
+
+This should be a list of mml tags to quote before saving. It is
+recommended that the list includes \"secure\".
+
+If you include \"part\" then attachments will not be saved with
+the draft -- if not then they will be saved with the draft. The
+former means the attachments may not still exist when you resume
+the message, the latter means that the attachments as they were
+when you postponed will be sent with the resumed message.
+
+Note you may get strange results if you change this between
+postponing and resuming a message."
+  :type '(repeat string)
+  :group 'notmuch-send)
+
+(defvar notmuch-message-draft-id nil
+  "Message-id of the most recent saved draft of this message")
+(make-variable-buffer-local 'notmuch-message-draft-id)
+
 (defun notmuch-message-mark-replied ()
   ;; get the in-reply-to header and parse it for the message id.
   (let ((rep (mail-header-parse-addresses (message-field-value 
"In-Reply-To"
@@ -45,7 +91,132 @@ the \"inbox\" and \"todo\" tags, you would set:
   (notmuch-tag (notmuch-id-to-query (car (car rep)))
   (notmuch-tag-change-list notmuch-message-replied-tags)
 
+(defun notmuch-message-mark-draft-deleted ()
+  "Tag the last saved draft deleted.
+
+Used when a new version is saved, or the message is sent."
+  (when notmuch-message-draft-id
+(notmuch-tag notmuch-message-draft-id '("+deleted"
+
+(defun notmuch-message-quote-some-mml ()
+  "Quote the mml tags in `notmuch-message-quoted-tags`."
+  ;; This is copied from mml-quote-region but only quotes the
+  ;; specified tags.
+  (when notmuch-message-quoted-tags
+(save-excursion
+  (let ((re (concat "<#!*/?\\("
+   (mapconcat 'identity notmuch-message-quoted-tags "\\|")
+   "\\)")))
+   (message-goto-body)
+   (while (re-search-forward re nil t)
+ ;; Insert ! after the #.
+ (goto-char (+ (match-beginning 0) 2))
+ (insert "!"))
+
+(defun notmuch-message-unquote-some-mml ()
+  "Unquote the mml tags in `notmuch-message-quoted-tags`."
+  (when notmuch-message-quoted-tags
+(save-excursion
+  (let ((re (concat "<#!+/?\\("
+   (mapconcat 'identity notmuch-message-quoted-tags "\\|")
+   "\\)")))
+   (message-goto-body)
+   (while (re-search-forward re nil t)
+ ;; Remove one ! from after the #.
+ (goto-char (+ (match-beginning 0) 2))
+ (delete-char 1))
+
+(defun notmuch-message-save-draft ()
+  "Save the current draft message in the notmuch database.
+
+This saves the current message in the database