1#! /usr/bin/env python3
3"""
4Add a user to to the uid/maintainer/fingerprint table and
5add his key to the GPGKeyring
7@contact: Debian FTP Master <ftpmaster@debian.org>
8@copyright: 2004, 2009 Joerg Jaspert <joerg@ganneff.de>
9@license: GNU General Public License version 2 or later
10"""
12################################################################################
13# <elmo> wow, sounds like it'll be a big step up.. configuring dak on a
14# new machine even scares me :)
15################################################################################
17# You don't want to read this script if you know python.
18# I know what I say. I dont know python and I wrote it. So go and read some other stuff.
20import subprocess
21import sys
22from typing import NoReturn
24import apt_pkg
26from daklib import utils
27from daklib.dbconn import DBConn, get_active_keyring_paths, get_or_set_uid
28from daklib.regexes import (
29 re_gpg_fingerprint_colon,
30 re_user_address,
31 re_user_mails,
32 re_user_name,
33)
35################################################################################
37Cnf = None
38Logger = None
40################################################################################
43def usage(exit_code: int = 0) -> NoReturn:
44 print(
45 """Usage: add-user [OPTION]...
46Adds a new user to the dak databases and keyrings
48 -k, --key keyid of the User
49 -u, --user userid of the User
50 -h, --help show this help and exit."""
51 )
52 sys.exit(exit_code)
55################################################################################
58def main():
59 global Cnf
60 keyrings = None
62 Cnf = utils.get_conf()
64 Arguments = [
65 ("h", "help", "Add-User::Options::Help"),
66 ("k", "key", "Add-User::Options::Key", "HasArg"),
67 ("u", "user", "Add-User::Options::User", "HasArg"),
68 ]
70 for i in ["help"]:
71 key = "Add-User::Options::%s" % i
72 if key not in Cnf: 72 ↛ 70line 72 didn't jump to line 70, because the condition on line 72 was never false
73 Cnf[key] = ""
75 apt_pkg.parse_commandline(Cnf, Arguments, sys.argv)
77 Options = Cnf.subtree("Add-User::Options")
78 if Options["help"]: 78 ↛ 81line 78 didn't jump to line 81, because the condition on line 78 was never false
79 usage()
81 session = DBConn().session()
83 if not keyrings:
84 keyrings = get_active_keyring_paths()
86 cmd = [
87 "gpg",
88 "--with-colons",
89 "--no-secmem-warning",
90 "--no-auto-check-trustdb",
91 "--with-fingerprint",
92 "--no-default-keyring",
93 ]
94 cmd.extend(utils.gpg_keyring_args(keyrings))
95 cmd.extend(["--list-key", "--", Cnf["Add-User::Options::Key"]])
96 output = subprocess.check_output(cmd).rstrip()
97 m = re_gpg_fingerprint_colon.search(output)
98 if not m:
99 print(output)
100 utils.fubar(
101 "0x%s: (1) No fingerprint found in gpg output but it returned 0?\n%s"
102 % (
103 Cnf["Add-User::Options::Key"],
104 utils.prefix_multi_line_string(output, " [GPG output:] "),
105 )
106 )
107 primary_key = m.group(1)
108 primary_key = primary_key.replace(" ", "")
110 uid = ""
111 if "Add-User::Options::User" in Cnf and Cnf["Add-User::Options::User"]:
112 uid = Cnf["Add-User::Options::User"]
113 name = Cnf["Add-User::Options::User"]
114 else:
115 u = re_user_address.search(output)
116 if not u:
117 print(output)
118 utils.fubar(
119 "0x%s: (2) No userid found in gpg output but it returned 0?\n%s"
120 % (
121 Cnf["Add-User::Options::Key"],
122 utils.prefix_multi_line_string(output, " [GPG output:] "),
123 )
124 )
125 uid = u.group(1)
126 n = re_user_name.search(output)
127 name = n.group(1)
129 # Look for all email addresses on the key.
130 emails = []
131 for line in output.split("\n"):
132 e = re_user_mails.search(line)
133 if not e:
134 continue
135 emails.append(e.group(2))
137 print(
138 "0x%s -> %s <%s> -> %s -> %s"
139 % (Cnf["Add-User::Options::Key"], name, emails[0], uid, primary_key)
140 )
142 prompt = "Add user %s with above data (y/N) ? " % (uid)
143 yn = utils.input_or_exit(prompt).lower()
145 if yn == "y":
146 # Create an account for the user?
147 summary = ""
149 # Now add user to the database.
150 # Note that we provide a session, so we're responsible for committing
151 uidobj = get_or_set_uid(uid, session=session)
152 uid_id = uidobj.uid_id
153 session.commit()
155 # Lets add user to the email-whitelist file if its configured.
156 if "Dinstall::MailWhiteList" in Cnf and Cnf["Dinstall::MailWhiteList"] != "":
157 with open(Cnf["Dinstall::MailWhiteList"], "a") as f:
158 for mail in emails:
159 f.write(mail + "\n")
161 print(
162 "Added:\nUid:\t %s (ID: %s)\nMaint:\t %s\nFP:\t %s"
163 % (uid, uid_id, name, primary_key)
164 )
166 # Should we send mail to the newly added user?
167 if Cnf.find_b("Add-User::SendEmail"):
168 mail = name + "<" + emails[0] + ">"
169 Subst = {}
170 Subst["__NEW_MAINTAINER__"] = mail
171 Subst["__UID__"] = uid
172 Subst["__KEYID__"] = Cnf["Add-User::Options::Key"]
173 Subst["__PRIMARY_KEY__"] = primary_key
174 Subst["__FROM_ADDRESS__"] = Cnf["Dinstall::MyEmailAddress"]
175 Subst["__ADMIN_ADDRESS__"] = Cnf["Dinstall::MyAdminAddress"]
176 Subst["__HOSTNAME__"] = Cnf["Dinstall::MyHost"]
177 Subst["__DISTRO__"] = Cnf["Dinstall::MyDistribution"]
178 Subst["__SUMMARY__"] = summary
179 new_add_message = utils.TemplateSubst(
180 Subst, Cnf["Dir::Templates"] + "/add-user.added"
181 )
182 utils.send_mail(new_add_message)
184 else:
185 uid = None
188#######################################################################################
191if __name__ == "__main__":
192 main()