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
|
# -*- coding: utf-8 -*-
"""
grumpy.utils
~~~~~~~~~~~~
Miscellaneous utils for authentication, mailing and pagination.
:copyright: (c) 2010 Priit Laes
"""
from flask import flash, g, redirect, request, url_for, Response
from functools import wraps
from smtplib import SMTP, SMTPException
from email.mime.text import MIMEText
from pkgcore.ebuild.cpv import native_ver_cmp
from . import app
def compare_version(ver1, ver2):
"""Compares two version strings."""
return native_ver_cmp(ver1, '', ver2, '')
def authenticate():
"""Sends a 401 response that enables basic HTTP auth"""
return Response('Could not verify your access level for that URL.\n'
'You have to login with proper credentials', 401,
{'WWW-Authenticate': 'Basic realm="Login required"'})
def check_auth(username, password):
"""Checks username password against ones stored in configuration."""
return username == app.config['TINDERBOX_USER'] and \
password == app.config['TINDERBOX_PASS']
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
if not g.user:
flash(u'This view requires valid user')
return redirect(url_for('index'))
return f(*args, **kwargs)
return decorated
def requires_auth_basic(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth or not check_auth(auth.username, auth.password):
return authenticate()
return f(*args, **kwargs)
return decorated
def send_email(recipients, subject, text):
"""Send mail using EMail class."""
return EMail(recipients, subject, text).send()
class EMail(object):
def __init__(self, recipients=None, subject=None, text=''):
# FIXME: Use app.config for from address
self.from_addr = 'noreply-grumpy@example.com'
self.subject = u' '.join(subject.splitlines())
self.to_addr = []
if isinstance(recipients, basestring):
self.to_addr.append(recipients)
else:
for addr in recipients:
self.to_addr.append(addr)
self.text = text
def as_message(self):
"""Return the email as MIMEText object."""
if not self.subject or not self.text or not self.to_addr:
raise RuntimeError("Not all mailing parameters filled in")
msg = MIMEText(self.text.encode('utf-8'))
# We set these ourself
del msg['Content-Transfer-Encoding']
del msg['Content-Type']
msg['From'] = self.from_addr.encode('utf-8')
msg['To'] = ', '.join(x.encode('utf-8') for x in self.to_addr)
msg['Subject'] = self.subject.encode('utf-8')
msg['Content-Transfer-Encoding'] = '8bit'
msg['Content-Type'] = 'text/plain; charset=utf-8'
return msg
def format(self, sep='\r\n'):
"""Convert the message into long string"""
return sep.join(self.as_message().as_string().splitlines())
def send(self):
try:
# TODO: Make configurable?
smtp = SMTP('localhost')
except SMTPException, e:
raise RuntimeError(str(e))
# TODO: Handle authentication and/or TLS
try:
try:
return smtp.sendmail(self.from_addr, self.to_addr, self.format())
except SMTPException, e:
raise RuntimeError(str(e))
finally:
# Close SMTP connection
smtp.quit()
|