From 23a2ada5f91db54eaee0c6aa38e2c3a1b2eaea5f Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Tue, 18 Aug 2015 18:52:22 +0000 Subject: [PATCH] checkpoint - Legacy-Id: 10027 --- ietf/ipr/mail.py | 8 +- ietf/ipr/tests.py | 4 +- ietf/ipr/views.py | 6 +- .../migrations/0002_auto_20150809_1314.py | 86 +++++++++- ietf/mailtoken/utils.py | 8 +- ietf/name/fixtures/names.json | 152 +++++++++++++++++- ietf/secr/meetings/views.py | 7 +- ietf/secr/sreq/views.py | 22 ++- ietf/settings.py | 2 +- 9 files changed, 262 insertions(+), 33 deletions(-) diff --git a/ietf/ipr/mail.py b/ietf/ipr/mail.py index 1532125dd..98aa16b3e 100644 --- a/ietf/ipr/mail.py +++ b/ietf/ipr/mail.py @@ -5,13 +5,13 @@ from dateutil.tz import tzoffset import os import pytz import re -from django.conf import settings from django.template.loader import render_to_string from ietf.ipr.models import IprEvent from ietf.message.models import Message from ietf.person.models import Person from ietf.utils.log import log +from ietf.mailtoken.utils import get_base_ipr_request_address # ---------------------------------------------------------------- # Date Functions @@ -89,7 +89,7 @@ def get_pseudo_submitter(ipr): def get_reply_to(): """Returns a new reply-to address for use with an outgoing message. This is an address with "plus addressing" using a random string. Guaranteed to be unique""" - local,domain = settings.IPR_EMAIL_TO.split('@') + local,domain = get_base_ipr_request_address().split('@') while True: rand = base64.urlsafe_b64encode(os.urandom(12)) address = "{}+{}@{}".format(local,rand,domain) @@ -167,7 +167,7 @@ def process_response_email(msg): to = message.get('To') # exit if this isn't a response we're interested in (with plus addressing) - local,domain = settings.IPR_EMAIL_TO.split('@') + local,domain = get_base_ipr_request_address().split('@') if not re.match(r'^{}\+[a-zA-Z0-9_\-]{}@{}'.format(local,'{16}',domain),to): return None @@ -193,4 +193,4 @@ def process_response_email(msg): ) log(u"Received IPR email from %s" % ietf_message.frm) - return ietf_message \ No newline at end of file + return ietf_message diff --git a/ietf/ipr/tests.py b/ietf/ipr/tests.py index b1496a2ec..907b920d1 100644 --- a/ietf/ipr/tests.py +++ b/ietf/ipr/tests.py @@ -3,7 +3,6 @@ import urllib from pyquery import PyQuery -from django.conf import settings from django.core.urlresolvers import reverse as urlreverse from ietf.doc.models import DocAlias @@ -16,6 +15,7 @@ from ietf.message.models import Message from ietf.utils.test_utils import TestCase, login_testing_unauthorized from ietf.utils.test_data import make_test_data from ietf.utils.mail import outbox +from ietf.mailtoken.utils import gather_addresses class IprTests(TestCase): @@ -519,7 +519,7 @@ I would like to revoke this declaration. From: joe@test.com Date: {} Subject: test -""".format(settings.IPR_EMAIL_TO,datetime.datetime.now().ctime()) +""".format(gather_addresses('ipr_disclosure_submitted'),datetime.datetime.now().ctime()) result = process_response_email(message_string) self.assertIsNone(result) diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py index 0058ca6c5..b0589ebc7 100644 --- a/ietf/ipr/views.py +++ b/ietf/ipr/views.py @@ -35,6 +35,7 @@ from ietf.person.models import Person from ietf.secr.utils.document import get_rfc_num, is_draft from ietf.utils.draft_search import normalize_draftname from ietf.utils.mail import send_mail, send_mail_message +from ietf.mailtoken.utils import gather_address_list # ---------------------------------------------------------------- # Globals @@ -379,7 +380,7 @@ def email(request, id): reply_to = get_reply_to() initial = { 'to': ipr.submitter_email, - 'frm': settings.IPR_EMAIL_TO, + 'frm': settings.IPR_EMAIL_FROM, 'subject': 'Regarding {}'.format(ipr.title), 'reply_to': reply_to, } @@ -474,7 +475,8 @@ def new(request, type, updates=None): desc="Disclosure Submitted") # send email notification - send_mail(request, settings.IPR_EMAIL_TO, ('IPR Submitter App', 'ietf-ipr@ietf.org'), + to = gather_address_list('ipr_disclosure_submitted') + send_mail(request, to, ('IPR Submitter App', 'ietf-ipr@ietf.org'), 'New IPR Submission Notification', "ipr/new_update_email.txt", {"ipr": disclosure,}) diff --git a/ietf/mailtoken/migrations/0002_auto_20150809_1314.py b/ietf/mailtoken/migrations/0002_auto_20150809_1314.py index 945ee6043..fbf0a564e 100644 --- a/ietf/mailtoken/migrations/0002_auto_20150809_1314.py +++ b/ietf/mailtoken/migrations/0002_auto_20150809_1314.py @@ -117,7 +117,7 @@ def make_recipients(apps): desc="The document's group's responsible AD(s) or IRTF chair", template=None) - rc(slug='internet_drafts', + rc(slug='internet_draft_requests', desc="The internet drafts ticketing system", template='internet-drafts@ietf.org') @@ -157,6 +157,18 @@ def make_recipients(apps): desc="Any personnel who were added or deleted when a group's personnel changes", template='{{ changed_personnel | join:", " }}') + rc(slug='session_requests', + desc="The session request ticketing system", + template='session-request@ietf.org') + + rc(slug='ipr_requests', + desc="The ipr disclosure handling system", + template='ietf-ipr@ietf.org') + + rc(slug='logged_in_person', + desc="The person currently logged into the datatracker who initiated a given action", + template='{% if person and person.email_address %}{{ person.email_address }}{% endif %}') + def make_mailtokens(apps): Recipient=apps.get_model('mailtoken','Recipient') @@ -467,7 +479,7 @@ def make_mailtokens(apps): mt_factory(slug='resurrection_requested', desc="Recipients of a request to change the state of a draft away from 'Dead'", - recipient_slugs=['internet_drafts',]) + recipient_slugs=['internet_draft_requests',]) mt_factory(slug='resurrection_completed', desc="Recipients when a draft resurrection request has been completed", @@ -477,7 +489,7 @@ def make_mailtokens(apps): mt_factory(slug='sub_manual_post_requested', desc="Recipients for a manual post request for a draft submission", - recipient_slugs=['internet_drafts', + recipient_slugs=['internet_draft_requests', ]) mt_factory(slug='sub_manual_post_requested_cc', @@ -552,6 +564,74 @@ def make_mailtokens(apps): 'group_changed_personnel', ]) + mt_factory(slug='session_requested', + desc="Recipients for a normal meeting session request", + recipient_slugs=['session_requests', + ]) + + mt_factory(slug='session_requested_cc', + desc="Copied on a normal meeting session request", + recipient_slugs=['group_mail_list', + 'group_chairs', + 'group_responsible_directors', + 'logged_in_person', + ]) + + mt_factory(slug='session_requested_long', + desc="Recipients for a meeting session request for more than 2 sessions", + recipient_slugs=['group_responsible_directors', + ]) + + mt_factory(slug='session_requested_long_cc', + desc="Copied on a meeting session request for more than 2 sessions", + recipient_slugs=['session_requests', + 'group_chairs', + 'logged_in_person', + ]) + + mt_factory(slug='session_request_cancelled', + desc="Recipients for a message cancelling a session request", + recipient_slugs=['session_requests', + ]) + + mt_factory(slug='session_request_cancelled_cc', + desc="Copied on a message cancelling a session request", + recipient_slugs=['group_mail_list', + 'group_chairs', + 'group_responsible_directors', + 'logged_in_person', + ]) + + mt_factory(slug='session_request_not_meeting', + desc="Recipients for a message noting a group plans to not meet", + recipient_slugs=['session_requests', + ]) + + mt_factory(slug='session_request_not_meeting_cc', + desc="Copied on a message noting a group plans to not meet", + recipient_slugs=['group_mail_list', + 'group_chairs', + 'group_responsible_directors', + 'logged_in_person', + ]) + + mt_factory(slug='session_scheduled', + desc="Recipients for details when a session has been scheduled", + recipient_slugs=['session_requester', + 'group_chairs', + ]) + + mt_factory(slug='session_scheduled_cc', + desc="Recipients for details when a session has been scheduled", + recipient_slugs=['group_mail_list', + 'group_responsible_directors', + ]) + + mt_factory(slug='ipr_disclosure_submitted', + desc="Recipients when an IPR notification is submitted", + recipient_slugs=['ipr_requests', + ]) + def forward(apps, schema_editor): make_recipients(apps) diff --git a/ietf/mailtoken/utils.py b/ietf/mailtoken/utils.py index 2cf14a0ff..56b330082 100644 --- a/ietf/mailtoken/utils.py +++ b/ietf/mailtoken/utils.py @@ -1,7 +1,6 @@ - from django.core.exceptions import ObjectDoesNotExist -from ietf.mailtoken.models import MailToken +from ietf.mailtoken.models import MailToken, Recipient def gather_address_list(slug,**kwargs): @@ -21,3 +20,8 @@ def gather_address_list(slug,**kwargs): def gather_addresses(slug,**kwargs): return ",\n ".join(gather_address_list(slug,**kwargs)) + +def get_base_ipr_request_address(): + return Recipient.objects.get(slug='ipr_requests').gather()[0] + + diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json index 88f2dc314..8e854a5bb 100644 --- a/ietf/name/fixtures/names.json +++ b/ietf/name/fixtures/names.json @@ -4557,7 +4557,23 @@ "desc": "The internet drafts ticketing system" }, "model": "mailtoken.recipient", - "pk": "internet_drafts" + "pk": "internet_draft_requests" +}, +{ + "fields": { + "template": "ietf-ipr@ietf.org", + "desc": "The ipr disclosure handling system" + }, + "model": "mailtoken.recipient", + "pk": "ipr_requests" +}, +{ + "fields": { + "template": "{% if person and person.email_address %}{{ person.email_address }}{% endif %}", + "desc": "The person currently logged into the datatracker who initiated a given action" + }, + "model": "mailtoken.recipient", + "pk": "logged_in_person" }, { "fields": { @@ -4575,6 +4591,14 @@ "model": "mailtoken.recipient", "pk": "rfc_editor_if_doc_in_queue" }, +{ + "fields": { + "template": "session-request@ietf.org", + "desc": "The session request ticketing system" + }, + "model": "mailtoken.recipient", + "pk": "session_requests" +}, { "fields": { "template": null, @@ -5047,6 +5071,16 @@ "model": "mailtoken.mailtoken", "pk": "group_personnel_change" }, +{ + "fields": { + "recipients": [ + "ipr_requests" + ], + "desc": "Recipients when an IPR notification is submitted" + }, + "model": "mailtoken.mailtoken", + "pk": "ipr_disclosure_submitted" +}, { "fields": { "recipients": [ @@ -5226,13 +5260,125 @@ { "fields": { "recipients": [ - "internet_drafts" + "internet_draft_requests" ], "desc": "Recipients of a request to change the state of a draft away from 'Dead'" }, "model": "mailtoken.mailtoken", "pk": "resurrection_requested" }, +{ + "fields": { + "recipients": [ + "session_requests" + ], + "desc": "Recipients for a normal meeting session request" + }, + "model": "mailtoken.mailtoken", + "pk": "session_requested" +}, +{ + "fields": { + "recipients": [ + "group_chairs", + "group_mail_list", + "group_responsible_directors", + "logged_in_person" + ], + "desc": "Copied on a normal meeting session request" + }, + "model": "mailtoken.mailtoken", + "pk": "session_requested_cc" +}, +{ + "fields": { + "recipients": [ + "group_responsible_directors" + ], + "desc": "Recipients for a meeting session request for more than 2 sessions" + }, + "model": "mailtoken.mailtoken", + "pk": "session_requested_long" +}, +{ + "fields": { + "recipients": [ + "group_chairs", + "logged_in_person", + "session_requests" + ], + "desc": "Copied on a meeting session request for more than 2 sessions" + }, + "model": "mailtoken.mailtoken", + "pk": "session_requested_long_cc" +}, +{ + "fields": { + "recipients": [ + "session_requests" + ], + "desc": "Recipients for a message cancelling a session request" + }, + "model": "mailtoken.mailtoken", + "pk": "session_request_cancelled" +}, +{ + "fields": { + "recipients": [ + "group_chairs", + "group_mail_list", + "group_responsible_directors", + "logged_in_person" + ], + "desc": "Copied on a message cancelling a session request" + }, + "model": "mailtoken.mailtoken", + "pk": "session_request_cancelled_cc" +}, +{ + "fields": { + "recipients": [ + "session_requests" + ], + "desc": "Recipients for a message noting a group plans to not meet" + }, + "model": "mailtoken.mailtoken", + "pk": "session_request_not_meeting" +}, +{ + "fields": { + "recipients": [ + "group_chairs", + "group_mail_list", + "group_responsible_directors", + "logged_in_person" + ], + "desc": "Copied on a message noting a group plans to not meet" + }, + "model": "mailtoken.mailtoken", + "pk": "session_request_not_meeting_cc" +}, +{ + "fields": { + "recipients": [ + "group_chairs" + ], + "desc": "Recipients for details when a session has been scheduled" + }, + "model": "mailtoken.mailtoken", + "pk": "session_scheduled" +}, +{ + "fields": { + "recipients": [ + "group_mail_list", + "group_responsible_directors" + ], + "desc": "Recipients for details when a session has been scheduled" + }, + "model": "mailtoken.mailtoken", + "pk": "session_scheduled_cc" +}, { "fields": { "recipients": [ @@ -5297,7 +5443,7 @@ { "fields": { "recipients": [ - "internet_drafts" + "internet_draft_requests" ], "desc": "Recipients for a manual post request for a draft submission" }, diff --git a/ietf/secr/meetings/views.py b/ietf/secr/meetings/views.py index 7a66eb622..827298278 100644 --- a/ietf/secr/meetings/views.py +++ b/ietf/secr/meetings/views.py @@ -25,8 +25,8 @@ from ietf.secr.meetings.forms import ( BaseMeetingRoomFormSet, MeetingModelForm, from ietf.secr.proceedings.views import build_choices, handle_upload_file, make_directories from ietf.secr.sreq.forms import GroupSelectForm from ietf.secr.sreq.views import get_initial_session -from ietf.secr.utils.mail import get_cc_list from ietf.secr.utils.meeting import get_session, get_timeslot +from ietf.mailtoken.utils import gather_address_list # prep for agenda changes @@ -188,9 +188,8 @@ def send_notifications(meeting, groups, person): now = datetime.datetime.now() for group in groups: sessions = group.session_set.filter(meeting=meeting) - to_email = sessions[0].requested_by.role_email('chair').address - # TODO confirm list, remove requested_by from cc, add session-request@ietf.org? - cc_list = get_cc_list(group) + to_email = gather_address_list('session_scheduled',group=group,person=sessions[0].requested_by) + cc_list = gather_address_list('session_scheduled_cc',group=group,person=sessions[0].requested_by) from_email = ('"IETF Secretariat"','agenda@ietf.org') if len(sessions) == 1: subject = '%s - Requested session has been scheduled for IETF %s' % (group.acronym, meeting.number) diff --git a/ietf/secr/sreq/views.py b/ietf/secr/sreq/views.py index a02347611..2f3ad1e1a 100644 --- a/ietf/secr/sreq/views.py +++ b/ietf/secr/sreq/views.py @@ -14,13 +14,14 @@ from ietf.name.models import SessionStatusName, ConstraintName from ietf.secr.sreq.forms import SessionForm, GroupSelectForm, ToolStatusForm from ietf.secr.utils.decorators import check_permissions from ietf.secr.utils.group import groups_by_session -from ietf.secr.utils.mail import get_ad_email_list, get_chair_email_list, get_cc_list from ietf.utils.mail import send_mail from ietf.person.models import Person +from ietf.mailtoken.utils import gather_address_list # ------------------------------------------------- # Globals # ------------------------------------------------- +#TODO: DELETE SESSION_REQUEST_EMAIL = 'session-request@ietf.org' AUTHORIZED_ROLES=('WG Chair','WG Secretary','RG Chair','IAB Group Chair','Area Director','Secretariat','Team Chair','IRTF Chair') @@ -112,8 +113,8 @@ def send_notification(group,meeting,login,session,action): session argument is a dictionary of fields from the session request form action argument is a string [new|update]. ''' - to_email = SESSION_REQUEST_EMAIL - cc_list = get_cc_list(group, login) + to_email = gather_address_list('session_requested',group=group,person=login) + cc_list = gather_address_list('session_requested_cc',group=group,person=login) from_email = ('"IETF Meeting Session Request Tool"','session_request_developers@ietf.org') subject = '%s - New Meeting Session Request for IETF %s' % (group.acronym, meeting.number) template = 'sreq/session_request_notification.txt' @@ -136,11 +137,8 @@ def send_notification(group,meeting,login,session,action): # change headers TO=ADs, CC=session-request, submitter and cochairs if session.get('length_session3',None): context['session']['num_session'] = 3 - to_email = get_ad_email_list(group) - cc_list = get_chair_email_list(group) - cc_list.append(SESSION_REQUEST_EMAIL) - if login.role_email(role_name='wg').address not in cc_list: - cc_list.append(login.role_email(role_name='wg').address) + to_email = gather_address_list('session_requested_long',group=group,person=login) + cc_list = gather_address_list('session_requested_long_cc',group=group,person=login) subject = '%s - Request for meeting session approval for IETF %s' % (group.acronym, meeting.number) template = 'sreq/session_approval_notification.txt' #status_text = 'the %s Directors for approval' % group.parent @@ -211,8 +209,8 @@ def cancel(request, acronym): session.scheduledsession_set.all().delete() # send notifitcation - to_email = SESSION_REQUEST_EMAIL - cc_list = get_cc_list(group, login) + to_email = gather_address_list('session_request_cancelled',group=group,person=login) + cc_list = gather_address_list('session_request_cancelled_cc',group=group,person=login) from_email = ('"IETF Meeting Session Request Tool"','session_request_developers@ietf.org') subject = '%s - Cancelling a meeting request for IETF %s' % (group.acronym, meeting.number) send_mail(request, to_email, from_email, subject, 'sreq/session_cancel_notification.txt', @@ -628,8 +626,8 @@ def no_session(request, acronym): session_save(session) # send notification - to_email = SESSION_REQUEST_EMAIL - cc_list = get_cc_list(group, login) + to_email = gather_address_list('session_request_not_meeting',group=group,person=login) + cc_list = gather_address_list('session_request_not_meeting_cc',group=group,person=login) from_email = ('"IETF Meeting Session Request Tool"','session_request_developers@ietf.org') subject = '%s - Not having a session at IETF %s' % (group.acronym, meeting.number) send_mail(request, to_email, from_email, subject, 'sreq/not_meeting_notification.txt', diff --git a/ietf/settings.py b/ietf/settings.py index b45d96396..1ccf829cf 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -388,7 +388,7 @@ CACHES = { } } -IPR_EMAIL_TO = 'ietf-ipr@ietf.org' +IPR_EMAIL_FROM = 'ietf-ipr@ietf.org' IANA_EVAL_EMAIL = "drafts-eval@icann.org"