Coverage for dak/add_user.py: 25%
82 statements
« prev ^ index » next coverage.py v7.6.0, created at 2026-01-04 16:18 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2026-01-04 16:18 +0000
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() -> None:
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 always true
73 Cnf[key] = "" # type: ignore[index]
75 apt_pkg.parse_commandline(Cnf, Arguments, sys.argv) # type: ignore[attr-defined]
77 Options = Cnf.subtree("Add-User::Options") # type: ignore[attr-defined]
78 if Options["help"]: 78 ↛ 81line 78 didn't jump to line 81 because the condition on line 78 was always true
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, text=True).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 assert n is not None
128 name = n.group(1)
130 # Look for all email addresses on the key.
131 emails = []
132 for line in output.split("\n"):
133 e = re_user_mails.search(line)
134 if not e:
135 continue
136 emails.append(e.group(2))
138 print(
139 "0x%s -> %s <%s> -> %s -> %s"
140 % (Cnf["Add-User::Options::Key"], name, emails[0], uid, primary_key)
141 )
143 prompt = "Add user %s with above data (y/N) ? " % (uid)
144 if utils.input_or_exit(prompt).lower() != "y":
145 return
147 # Create an account for the user?
148 summary = ""
150 # Now add user to the database.
151 # Note that we provide a session, so we're responsible for committing
152 uidobj = get_or_set_uid(uid, session=session)
153 uid_id = uidobj.uid_id
154 session.commit()
156 # Lets add user to the email-whitelist file if its configured.
157 if "Dinstall::MailWhiteList" in Cnf and Cnf["Dinstall::MailWhiteList"] != "":
158 with open(Cnf["Dinstall::MailWhiteList"], "a") as f:
159 for mail in emails:
160 f.write(mail + "\n")
162 print(
163 "Added:\nUid:\t %s (ID: %s)\nMaint:\t %s\nFP:\t %s"
164 % (uid, uid_id, name, primary_key)
165 )
167 # Should we send mail to the newly added user?
168 if Cnf.find_b("Add-User::SendEmail"):
169 mail = name + "<" + emails[0] + ">"
170 Subst = {}
171 Subst["__NEW_MAINTAINER__"] = mail
172 Subst["__UID__"] = uid
173 Subst["__KEYID__"] = Cnf["Add-User::Options::Key"]
174 Subst["__PRIMARY_KEY__"] = primary_key
175 Subst["__FROM_ADDRESS__"] = Cnf["Dinstall::MyEmailAddress"]
176 Subst["__ADMIN_ADDRESS__"] = Cnf["Dinstall::MyAdminAddress"]
177 Subst["__HOSTNAME__"] = Cnf["Dinstall::MyHost"]
178 Subst["__DISTRO__"] = Cnf["Dinstall::MyDistribution"]
179 Subst["__SUMMARY__"] = summary
180 new_add_message = utils.TemplateSubst(
181 Subst, Cnf["Dir::Templates"] + "/add-user.added"
182 )
183 utils.send_mail(new_add_message)
186#######################################################################################
189if __name__ == "__main__":
190 main()