2 # -*- coding: utf-8 -*-
4 import sys, os, random, MySQLdb, subprocess, time, string, argparse
5 import smtplib, email.mime.text, email.utils
7 from templates import *
10 random.seed = os.urandom(32)
13 db = MySQLdb.connect(user=DB_USER, passwd=DB_PW, db=DB_NAME, charset='utf8')
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)
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")
29 def db_run(query, *args):
30 cursor = db_execute(query, args)
33 def new_user(name, hash, ):
34 db_run('INSERT INTO users (username, password, active) VALUES (%s, %s, -1)', name, hash)
36 def new_alias(name, alias):
37 db_run('INSERT INTO aliases (mail, user) VALUES (%s, %s)', name, alias)
39 # interaction with dbadm pw
41 return subprocess.check_output(["doveadm", "pw", "-s", "SHA512-CRYPT", "-r", str(64*1024), "-p", plain]).decode('utf-8').strip()
44 def gen_pw(length = 12):
45 chars = string.ascii_letters + string.digits
46 return ''.join(random.choice(chars) for i in range(length))
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
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())
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",
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()
84 args.mail = args.forward
86 print("Whom should I send the mail to? Please use `-m <address>`.")
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))
95 new_user(args.username, gen_hash(password))
96 print("Created {} with password {}".format(args.username, password))
98 new_alias(args.username, args.forward)
99 print("Forwarded {} to {}".format(args.username, args.forward))
101 send_mail(args.username, args.mail, password, args.forward)
102 print("Sent mail about the new account to {}".format(args.mail))