File size: 5,403 Bytes
9dd30d3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.template import Template
import logging
class EmailService:
def __init__(self, smtp_server="smtp.gmail.com", smtp_port=587):
self.smtp_server = smtp_server
self.smtp_port = smtp_port
self.username = None
self.password = None
self.logger = logging.getLogger(__name__)
def configure_smtp(self, username, password):
"""Configure SMTP credentials"""
self.username = username
self.password = password
def send_password_reset_email(self, recipient_email, reset_token):
"""Send password reset email to user"""
try:
# Create message
message = MIMEMultipart("alternative")
message["Subject"] = "Password Reset Request"
message["From"] = self.username
message["To"] = recipient_email
# Create HTML content
html_content = self._generate_reset_email_html(reset_token)
html_part = MIMEText(html_content, "html")
message.attach(html_part)
# Send email
return self._send_email(message)
except Exception as e:
self.logger.error(f"Error sending password reset email: {str(e)}")
return False, f"Failed to send email: {str(e)}"
def send_notification_email(self, recipient_email, subject, content):
"""Send general notification email"""
try:
message = MIMEMultipart()
message["Subject"] = subject
message["From"] = self.username
message["To"] = recipient_email
text_part = MIMEText(content, "plain")
message.attach(text_part)
return self._send_email(message)
except Exception as e:
self.logger.error(f"Error sending notification email: {str(e)}")
return False, f"Failed to send email: {str(e)}"
def _send_email(self, message):
"""Internal method to send email via SMTP"""
try:
# Create secure connection
context = ssl.create_default_context()
with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
server.starttls(context=context)
# Check if credentials are configured
if not self.username or not self.password:
raise Exception("SMTP credentials not configured")
server.login(self.username, self.password)
# Send email
text = message.as_string()
server.sendmail(message["From"], message["To"], text)
self.logger.info(f"Email sent successfully to {message['To']}")
return True, "Email sent successfully"
except smtplib.SMTPAuthenticationError:
error_msg = "SMTP authentication failed - check credentials"
self.logger.error(error_msg)
return False, error_msg
except smtplib.SMTPConnectError:
error_msg = "Failed to connect to SMTP server"
self.logger.error(error_msg)
return False, error_msg
except Exception as e:
error_msg = f"Unexpected error sending email: {str(e)}"
self.logger.error(error_msg)
return False, error_msg
def _generate_reset_email_html(self, reset_token):
"""Generate HTML content for password reset email"""
html_template = """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Password Reset</title>
</head>
<body>
<div style="max-width: 600px; margin: 0 auto; padding: 20px;">
<h2>Password Reset Request</h2>
<p>You have requested a password reset for your account.</p>
<p>Click the link below to reset your password:</p>
<a href="https://yourapp.com/reset-password?token={token}"
style="background-color: #4CAF50; color: white; padding: 10px 20px;
text-decoration: none; border-radius: 4px;">
Reset Password
</a>
<p>If you did not request this reset, please ignore this email.</p>
<p>This link will expire in 24 hours.</p>
</div>
</body>
</html>
"""
return html_template.format(token=reset_token)
def test_connection(self):
"""Test SMTP connection and configuration"""
try:
context = ssl.create_default_context()
with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
server.starttls(context=context)
if self.username and self.password:
server.login(self.username, self.password)
return True, "SMTP connection successful"
except Exception as e:
return False, f"SMTP connection failed: {str(e)}" |