Validate email configuration completeness. Returns: List of validation error messages (empty if valid)
(self)
| 200 | _oauth_tokens_updated: bool = field(default=False, init=False) |
| 201 | |
| 202 | def validate(self) -> List[str]: |
| 203 | """ |
| 204 | Validate email configuration completeness. |
| 205 | |
| 206 | Returns: |
| 207 | List of validation error messages (empty if valid) |
| 208 | """ |
| 209 | errors = [] |
| 210 | |
| 211 | if not self.provider: |
| 212 | errors.append("Provider is required") |
| 213 | |
| 214 | if not self.from_address: |
| 215 | errors.append("From address is required") |
| 216 | |
| 217 | if self.provider == 'smtp': |
| 218 | if not self.smtp_host: |
| 219 | errors.append("SMTP host is required") |
| 220 | if not self.smtp_username: |
| 221 | errors.append("SMTP username is required") |
| 222 | if not self.smtp_password: |
| 223 | errors.append("SMTP password is required") |
| 224 | |
| 225 | elif self.provider == 'ses': |
| 226 | if not self.aws_region: |
| 227 | errors.append("AWS region is required for SES") |
| 228 | if not self.aws_access_key: |
| 229 | errors.append("AWS access key is required for SES") |
| 230 | if not self.aws_secret_key: |
| 231 | errors.append("AWS secret key is required for SES") |
| 232 | |
| 233 | elif self.provider == 'sendgrid': |
| 234 | if not self.sendgrid_api_key: |
| 235 | errors.append("SendGrid API key is required") |
| 236 | |
| 237 | elif self.provider in ('gmail-oauth', 'microsoft-oauth'): |
| 238 | # OAuth providers require either interactive auth OR manual token entry |
| 239 | if not self.oauth_client_id: |
| 240 | errors.append(f"OAuth client ID is required for {self.provider}") |
| 241 | if not self.oauth_client_secret: |
| 242 | errors.append(f"OAuth client secret is required for {self.provider}") |
| 243 | |
| 244 | # If no access token, we'll do interactive OAuth flow |
| 245 | # If access token provided, we should also have refresh token |
| 246 | if self.oauth_access_token and not self.oauth_refresh_token: |
| 247 | errors.append("OAuth refresh token is required when access token is provided") |
| 248 | |
| 249 | # Microsoft requires tenant ID |
| 250 | if self.provider == 'microsoft-oauth' and not self.oauth_tenant_id: |
| 251 | errors.append("OAuth tenant ID is required for Microsoft (use 'common' for multi-tenant)") |
| 252 | |
| 253 | else: |
| 254 | errors.append(f"Unknown provider: {self.provider}") |
| 255 | |
| 256 | return errors |
| 257 | |
| 258 | def is_oauth_provider(self) -> bool: |
| 259 | """Check if this config uses OAuth authentication.""" |
no outgoing calls