|
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