1.1 --- a/MoinMessageSupport.py Thu Nov 14 18:43:10 2013 +0100
1.2 +++ b/MoinMessageSupport.py Tue Dec 17 14:11:38 2013 +0100
1.3 @@ -118,6 +118,8 @@
1.4
1.5 homedir = self.get_homedir()
1.6 if not homedir:
1.7 + writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden")
1.8 + request.write("This site is not configured for this request.")
1.9 return
1.10
1.11 gpg = GPG(homedir)
1.12 @@ -260,7 +262,7 @@
1.13 getattr(request.cfg, "moinmessage_gpg_relays_page", "MoinMessageRelayDict"),
1.14 request)
1.15
1.16 -def get_recipients(request, main=False):
1.17 +def get_recipients(request, main=False, sending=True, fetching=True):
1.18
1.19 """
1.20 Return the recipients dictionary by first obtaining the page in which it
1.21 @@ -270,6 +272,10 @@
1.22 When 'main' is specified and set to a true value, only a dictionary under
1.23 the site root is consulted.
1.24
1.25 + When 'sending' or 'fetching' is specified and set to a false value, any
1.26 + recipients of the indicated type will be excluded from the result of this
1.27 + function.
1.28 +
1.29 The name of the subpage is defined by the configuration setting
1.30 'moinmessage_gpg_recipients_page', which if absent is set to
1.31 "MoinMessageRecipientsDict".
1.32 @@ -285,9 +291,9 @@
1.33 if homewiki == "Self":
1.34 recipients = getWikiDict("%s/%s" % (homepage, subpage), request)
1.35 if recipients:
1.36 - return recipients
1.37 + return filter_recipients(recipients, sending, fetching)
1.38
1.39 - return getWikiDict(subpage, request)
1.40 + return filter_recipients(getWikiDict(subpage, request), sending, fetching)
1.41
1.42 def get_username_for_fingerprint(request, fingerprint):
1.43
1.44 @@ -310,7 +316,7 @@
1.45 else:
1.46 return None
1.47
1.48 -def get_recipient_details(request, recipient, main=False):
1.49 +def get_recipient_details(request, recipient, main=False, fetching=False):
1.50
1.51 """
1.52 Using the 'request', return a dictionary of details for the specified
1.53 @@ -319,6 +325,10 @@
1.54
1.55 When 'main' is specified and set to a true value, only the recipients
1.56 dictionary under the site root is consulted.
1.57 +
1.58 + When 'fetching' is specified and set to a true value, the recipient need
1.59 + not have a "type" or "location" defined, but it must have a "fingerprint"
1.60 + defined.
1.61 """
1.62
1.63 _ = request.getText
1.64 @@ -333,15 +343,35 @@
1.65
1.66 parameters = parseDictEntry(recipient_details, ("type", "location", "fingerprint",))
1.67
1.68 - if not parameters.has_key("type"):
1.69 + type = parameters.get("type")
1.70 + location = parameters.get("location")
1.71 + fingerprint = parameters.get("fingerprint")
1.72 +
1.73 + if type in (None, "none") and not fetching:
1.74 raise MoinMessageBadRecipient, _("The recipient details are missing a destination type.")
1.75
1.76 - if not parameters.has_key("location"):
1.77 + if type not in (None, "none") and not location:
1.78 raise MoinMessageBadRecipient, _("The recipient details are missing a location for sent messages.")
1.79
1.80 - if parameters["type"] in ("url", "relay") and not parameters.has_key("fingerprint"):
1.81 + if type in ("url", "relay", None, "none") and not fingerprint:
1.82 raise MoinMessageBadRecipient, _("The recipient details are missing a fingerprint for sending messages.")
1.83
1.84 return parameters
1.85
1.86 +def filter_recipients(recipients, sending, fetching):
1.87 +
1.88 + """
1.89 + Return a copy of the given 'recipients' dictionary retaining all entries
1.90 + that apply to the given 'sending' and 'fetching' criteria.
1.91 + """
1.92 +
1.93 + result = {}
1.94 + for recipient, parameters in recipients.items():
1.95 + if not fetching and parameters.get("type") in (None, "none"):
1.96 + continue
1.97 + if not sending and not parameters.get("fingerprint"):
1.98 + continue
1.99 + result[recipient] = parameters
1.100 + return result
1.101 +
1.102 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/README.txt Thu Nov 14 18:43:10 2013 +0100
2.2 +++ b/README.txt Tue Dec 17 14:11:38 2013 +0100
2.3 @@ -238,8 +238,12 @@
2.4 must be defined in the relays mapping (see below) and yield a URL that can
2.5 accept MoinMessage content.
2.6
2.7 -Where a type of "url" or "relay" has been given, a fingerprint must accompany
2.8 -this information in order to encrypt messages sent to the specified resource.
2.9 +Where the type is "none" or omitted completely, the recipient is any user that
2.10 +is allowed to fetch messages from the wiki.
2.11 +
2.12 +Where a type of "url", "relay" or "none" has been given (or if the type is
2.13 +omitted), a fingerprint must accompany this information in order to encrypt
2.14 +messages sent to the specified resource.
2.15
2.16 Each fingerprint corresponds to a key used by the wiki to encrypt messages and
2.17 by the remote site (as identified by the URL) to decrypt messages.
3.1 --- a/actions/FetchMessages.py Thu Nov 14 18:43:10 2013 +0100
3.2 +++ b/actions/FetchMessages.py Tue Dec 17 14:11:38 2013 +0100
3.3 @@ -9,7 +9,8 @@
3.4 from MoinSupport import getMetadata, writeHeaders, parseDictEntry
3.5 from MoinMessage import Message, GPG
3.6 from MoinMessageSupport import MoinMessageAction, \
3.7 - get_signing_users, get_recipients
3.8 + get_signing_users, get_recipient_details, \
3.9 + MoinMessageRecipientError
3.10 from email.mime.text import MIMEText
3.11 from email.parser import Parser
3.12 from itertools import islice
3.13 @@ -34,12 +35,14 @@
3.14 # NOTE: Could employ a more accurate content type.
3.15
3.16 if not content.get_content_type() == "text/plain":
3.17 - writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden")
3.18 + writeHeaders(request, "text/plain", getMetadata(self.page), "415 Unsupported Media Type")
3.19 request.write("The content does not appear to be a request for messages.")
3.20 return
3.21
3.22 homedir = self.get_homedir()
3.23 if not homedir:
3.24 + writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden")
3.25 + request.write("This site is not configured for this request.")
3.26 return
3.27
3.28 gpg = GPG(homedir)
3.29 @@ -57,18 +60,11 @@
3.30
3.31 # Get the recipient details.
3.32
3.33 - recipients = get_recipients(request)
3.34 - if not recipient or not recipients or not recipients.has_key(recipient):
3.35 + try:
3.36 + parameters = get_recipient_details(request, recipient, fetching=True)
3.37 + except MoinMessageRecipientError, exc:
3.38 writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden")
3.39 - request.write("The recipient does not appear to be registered for message delivery.")
3.40 - return
3.41 -
3.42 - recipient_details = recipients[recipient]
3.43 - parameters = parseDictEntry(recipient_details, ("type", "location", "fingerprint",))
3.44 -
3.45 - if not parameters.has_key("fingerprint"):
3.46 - writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden")
3.47 - request.write("The recipient does not appear to be registered for message delivery.")
3.48 + request.write(exc.message)
3.49 return
3.50
3.51 # Obtain commands from the payload, returning a collection of messages.
3.52 @@ -170,7 +166,6 @@
3.53
3.54 writeHeaders(request, "text/plain", getMetadata(self.page))
3.55 request.write(message.as_string())
3.56 - return 1, None
3.57
3.58 # Action function.
3.59
4.1 --- a/actions/SendMessage.py Thu Nov 14 18:43:10 2013 +0100
4.2 +++ b/actions/SendMessage.py Tue Dec 17 14:11:38 2013 +0100
4.3 @@ -72,7 +72,7 @@
4.4
4.5 # Get a list of potential recipients.
4.6
4.7 - recipients = get_recipients(request)
4.8 + recipients = get_recipients(request, fetching=False)
4.9
4.10 # Prepare the recipients list, selecting the specified recipients.
4.11