1818from openedx .core .djangoapps .site_configuration import helpers as configuration_helpers
1919from openedx .core .djangoapps .user_authn .utils import check_pwned_password
2020from openedx .core .lib .celery .task_utils import emulate_http_request
21+ from openedx .core .djangoapps .ace_common .utils import ENABLE_SES_FOR_ACCOUNT_ACTIVATION
2122
2223log = logging .getLogger ('edx.celery.task' )
2324
@@ -60,6 +61,9 @@ def send_activation_email(self, msg_string, from_address=None, site_id=None):
6061 max_retries = settings .RETRY_ACTIVATION_EMAIL_MAX_ATTEMPTS
6162 retries = self .request .retries
6263
64+ if msg .options is None :
65+ msg .options = {}
66+
6367 if from_address is None :
6468 from_address = configuration_helpers .get_value ('ACTIVATION_EMAIL_FROM_ADDRESS' ) or (
6569 configuration_helpers .get_value ('email_from_address' , settings .DEFAULT_FROM_EMAIL )
@@ -71,28 +75,98 @@ def send_activation_email(self, msg_string, from_address=None, site_id=None):
7175 site = Site .objects .get (id = site_id ) if site_id else Site .objects .get_current ()
7276 user = User .objects .get (id = msg .recipient .lms_user_id )
7377
78+ route_via_ses = ENABLE_SES_FOR_ACCOUNT_ACTIVATION .is_enabled ()
79+ sent_via_ses = False
80+
81+ if route_via_ses :
82+ msg .options .update ({
83+ 'override_default_channel' : 'django_email' ,
84+ 'transactional' : True ,
85+ 'from_address' : configuration_helpers .get_value (
86+ 'ACTIVATION_EMAIL_FROM_ADDRESS'
87+ ) or configuration_helpers .get_value (
88+ 'email_from_address' ,
89+ settings .DEFAULT_FROM_EMAIL
90+ ),
91+ })
92+
7493 try :
7594 with emulate_http_request (site = site , user = user ):
7695 ace .send (msg )
96+ sent_via_ses = route_via_ses
97+
7798 except RecoverableChannelDeliveryError :
78- log .info ('Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}' .format (
79- dest_addr = dest_addr ,
80- attempt = retries ,
81- max_attempts = max_retries
82- ))
99+ log .warning (
100+ "SES send failed for %s, falling back to default ACE channel" ,
101+ dest_addr ,
102+ exc_info = True ,
103+ )
104+
105+ if not route_via_ses :
106+ log .info (
107+ 'Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}' .format (
108+ dest_addr = dest_addr ,
109+ attempt = retries ,
110+ max_attempts = max_retries
111+ )
112+ )
113+ try :
114+ self .retry (
115+ countdown = settings .RETRY_ACTIVATION_EMAIL_TIMEOUT ,
116+ max_retries = max_retries
117+ )
118+ except MaxRetriesExceededError :
119+ log .error (
120+ 'Unable to send activation email to user from "%s" to "%s"' ,
121+ from_address ,
122+ dest_addr ,
123+ exc_info = True
124+ )
125+ return
126+
127+ _remove_ses_overrides (msg )
128+
83129 try :
84- self .retry (countdown = settings .RETRY_ACTIVATION_EMAIL_TIMEOUT , max_retries = max_retries )
85- except MaxRetriesExceededError :
86- log .error (
87- 'Unable to send activation email to user from "%s" to "%s"' ,
88- from_address ,
89- dest_addr ,
90- exc_info = True
130+ with emulate_http_request (site = site , user = user ):
131+ ace .send (msg )
132+ sent_via_ses = False
133+
134+ except RecoverableChannelDeliveryError :
135+ log .info (
136+ 'Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}' .format (
137+ dest_addr = dest_addr ,
138+ attempt = retries ,
139+ max_attempts = max_retries
140+ )
91141 )
142+ try :
143+ self .retry (
144+ countdown = settings .RETRY_ACTIVATION_EMAIL_TIMEOUT ,
145+ max_retries = max_retries
146+ )
147+ except MaxRetriesExceededError :
148+ log .error (
149+ 'Unable to send activation email to user from "%s" to "%s"' ,
150+ from_address ,
151+ dest_addr ,
152+ exc_info = True
153+ )
92154 except Exception :
93155 log .exception (
94156 'Unable to send activation email to user from "%s" to "%s"' ,
95157 from_address ,
96158 dest_addr ,
97159 )
98- raise Exception # lint-amnesty, pylint: disable=raise-missing-from
160+ raise
161+
162+ log .info (
163+ 'Activation email for %s sent via %s' ,
164+ dest_addr ,
165+ 'SES' if sent_via_ses else 'default ACE channel' ,
166+ )
167+
168+
169+ def _remove_ses_overrides (msg ):
170+ msg .options .pop ('override_default_channel' , None )
171+ msg .options .pop ('transactional' , None )
172+ msg .options .pop ('from_address' , None )
0 commit comments