|
1 | | -use crate::email::Email; |
| 1 | +use crate::email::EmailMessage; |
2 | 2 | use crate::schema::{emails, users}; |
3 | 3 | use crate::worker::Environment; |
| 4 | +use anyhow::Context; |
4 | 5 | use crates_io_worker::BackgroundJob; |
5 | 6 | use diesel::prelude::*; |
6 | 7 | use diesel_async::RunQueryDsl; |
| 8 | +use minijinja::context; |
7 | 9 | use std::collections::HashSet; |
8 | | -use std::fmt::{Display, Formatter}; |
9 | 10 | use std::sync::Arc; |
10 | 11 |
|
11 | 12 | /// See <https://github.com/rust-lang/team/pull/1197>. |
@@ -138,72 +139,32 @@ impl BackgroundJob for SyncAdmins { |
138 | 139 |
|
139 | 140 | let added_admins = format_repo_admins(&added_admin_ids); |
140 | 141 | let removed_admins = format_database_admins(&removed_admin_ids); |
141 | | - |
142 | | - let email = AdminAccountEmail::new(added_admins, removed_admins); |
| 142 | + let context = context! { added_admins, removed_admins }; |
143 | 143 |
|
144 | 144 | for database_admin in &database_admins { |
145 | | - let (_, _, email_address) = database_admin; |
| 145 | + let (github_id, login, email_address) = database_admin; |
146 | 146 | if let Some(email_address) = email_address { |
147 | | - if let Err(error) = ctx.emails.send(email_address, email.clone()).await { |
| 147 | + if let Err(error) = send_email(&ctx, email_address, &context).await { |
148 | 148 | warn!( |
149 | | - "Failed to send email to admin {} ({}, github_id: {}): {}", |
150 | | - database_admin.1, email_address, database_admin.0, error |
| 149 | + "Failed to send email to admin {login} ({email_address}, github_id: {github_id}): {error:?}", |
151 | 150 | ); |
152 | 151 | } |
153 | 152 | } else { |
154 | | - warn!( |
155 | | - "No email address found for admin {} (github_id: {})", |
156 | | - database_admin.1, database_admin.0 |
157 | | - ); |
| 153 | + warn!("No email address found for admin {login} (github_id: {github_id})",); |
158 | 154 | } |
159 | 155 | } |
160 | 156 |
|
161 | 157 | Ok(()) |
162 | 158 | } |
163 | 159 | } |
164 | 160 |
|
165 | | -#[derive(Debug, Clone)] |
166 | | -struct AdminAccountEmail { |
167 | | - added_admins: Vec<String>, |
168 | | - removed_admins: Vec<String>, |
169 | | -} |
170 | | - |
171 | | -impl AdminAccountEmail { |
172 | | - fn new(added_admins: Vec<String>, removed_admins: Vec<String>) -> Self { |
173 | | - Self { |
174 | | - added_admins, |
175 | | - removed_admins, |
176 | | - } |
177 | | - } |
178 | | -} |
179 | | - |
180 | | -impl Email for AdminAccountEmail { |
181 | | - fn subject(&self) -> String { |
182 | | - "crates.io: Admin account changes".into() |
183 | | - } |
184 | | - |
185 | | - fn body(&self) -> String { |
186 | | - self.to_string() |
187 | | - } |
188 | | -} |
189 | | - |
190 | | -impl Display for AdminAccountEmail { |
191 | | - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
192 | | - if !self.added_admins.is_empty() { |
193 | | - writeln!(f, "Granted admin access:\n")?; |
194 | | - for new_admin in &self.added_admins { |
195 | | - writeln!(f, "- {}", new_admin)?; |
196 | | - } |
197 | | - writeln!(f)?; |
198 | | - } |
199 | | - |
200 | | - if !self.removed_admins.is_empty() { |
201 | | - writeln!(f, "Revoked admin access:")?; |
202 | | - for obsolete_admin in &self.removed_admins { |
203 | | - writeln!(f, "- {}", obsolete_admin)?; |
204 | | - } |
205 | | - } |
206 | | - |
207 | | - Ok(()) |
208 | | - } |
| 161 | +async fn send_email( |
| 162 | + ctx: &Environment, |
| 163 | + address: &str, |
| 164 | + context: &minijinja::Value, |
| 165 | +) -> anyhow::Result<()> { |
| 166 | + let email = EmailMessage::from_template("admin_account", context); |
| 167 | + let email = email.context("Failed to render email template")?; |
| 168 | + let result = ctx.emails.send(address, email).await; |
| 169 | + result.context("Failed to send email") |
209 | 170 | } |
0 commit comments