add newmail script
[ansible.git] / roles / postfix / files / newmail / newmail
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3 from __future__ import print_function
4 import sys, os, random, MySQLdb, subprocess, time, string, argparse
5 import urllib, smtplib, email.mime.text, email.utils
6 from settings import *
7 from templates import *
8
9 # setup
10 random.seed = os.urandom(32)
11
12 # DB stuff
13 db = MySQLdb.connect(user=DB_USER, passwd=DB_PW, db=DB_NAME, charset='utf8')
14
15 def db_execute(query, args):
16    cursor = db.cursor(MySQLdb.cursors.DictCursor)
17    if len(args) == 1 and isinstance(args[0], dict): args = args[0] # einzelnes dict weiterreichen
18    cursor.execute(query, args)
19    return cursor
20
21 def db_fetch_one_row(query, *args):
22    cursor = db_execute(query, args)
23    result = cursor.fetchone()
24    if cursor.fetchone() is not None:
25       raise Exception("Found more than one result, only one was expected")
26    cursor.close()
27    return result
28
29 def db_run(query, *args):
30    cursor = db_execute(query, args)
31    cursor.close()
32
33 def new_user(name, hash, ):
34    db_run('INSERT INTO users (username, password, active) VALUES (%s, %s, -1)', name, hash)
35
36 def new_alias(name, alias):
37    db_run('INSERT INTO aliases (mail, user) VALUES (%s, %s)', name, alias)
38
39 # interaction with dbadm pw
40 def gen_hash(plain):
41    return subprocess.check_output(["doveadm", "pw", "-s", "SHA512-CRYPT", "-r", str(64*1024), "-p", plain]).decode('utf-8').strip()
42
43 # more tools
44 def gen_pw(length = 12):
45    chars = string.ascii_letters + string.digits
46    return ''.join(random.choice(chars) for i in range(length))
47
48 def send_mail(user, mail, password, forward):
49    assert password is not None, "Sending mail for non-password accounts not yet supported."
50    incoming = (INCOMING_FORWARD if forward else INCOMING_IMAP).format(password=password, user=user, host=HOST, forward=forward)
51    text = TEMPLATE.format(password=password, user=user, host=HOST, forward=forward, incoming=incoming)
52    subject = SUBJECT.format(user=user, host=HOST)
53    # construct mail content
54    msg = email.mime.text.MIMEText(text, 'plain', 'utf-8')
55    msg['Subject'] = subject
56    msg['Date'] = email.utils.formatdate(localtime=True)
57    msg['From'] = MAIL_ADDR
58    msg['To'] = mail
59    msg['Bcc'] = MAIL_ADDR
60    # put into envelope and send
61    s = smtplib.SMTP('localhost')
62    s.sendmail(MAIL_ADDR, [mail, MAIL_ADDR], msg.as_string())
63    s.quit()
64
65 # read command-line arguments
66 parser = argparse.ArgumentParser(description='Create a new e-mail user')
67 parser.add_argument("-u", "--username",
68                     dest="username", required=True,
69                     help="The name of the user (that's also its address).")
70 parser.add_argument("-f", "--forward",
71                     dest="forward",
72                     help="Where to forward emails to.")
73 #parser.add_argument("-p", "--password",
74 #                    action="store_true", dest="password",
75 #                    help="Whether to create an account and password for this user.")
76 parser.add_argument("-m", "--mail", nargs='?',
77                     action="store", dest="mail", const=True,
78                     help="Whether to notify the user about their new account.")
79 args = parser.parse_args()
80
81 # sanity check
82 if args.mail == True:
83    if args.forward:
84       args.mail = args.forward
85    else:
86       print("Whom should I send the mail to? Please use `-m <address>`.")
87       sys.exit(1)
88 domain = args.username.split('@')[-1]
89 if domain not in DOMAINS:
90    print("{} is not a domain we can handle mail for.".format(domain))
91    sys.exit(1)
92
93 # do stuff
94 password = gen_pw()
95 new_user(args.username, gen_hash(password))
96 print("Created {} with password {}".format(args.username, password))
97 if args.forward:
98    new_alias(args.username, args.forward)
99    print("Forwarded {} to {}".format(args.username, args.forward))
100 if args.mail:         
101    send_mail(args.username, args.mail, password, args.forward)
102    print("Sent mail about the new account to {}".format(args.mail))