1#! /usr/bin/env python3 

2 

3""" 

4Add a user to to the uid/maintainer/fingerprint table and 

5add his key to the GPGKeyring 

6 

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""" 

11 

12################################################################################ 

13# <elmo> wow, sounds like it'll be a big step up.. configuring dak on a 

14# new machine even scares me :) 

15################################################################################ 

16 

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. 

19 

20import subprocess 

21import sys 

22from typing import NoReturn 

23 

24import apt_pkg 

25 

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) 

34 

35################################################################################ 

36 

37Cnf = None 

38Logger = None 

39 

40################################################################################ 

41 

42 

43def usage(exit_code: int = 0) -> NoReturn: 

44 print( 

45 """Usage: add-user [OPTION]... 

46Adds a new user to the dak databases and keyrings 

47 

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) 

53 

54 

55################################################################################ 

56 

57 

58def main(): 

59 global Cnf 

60 keyrings = None 

61 

62 Cnf = utils.get_conf() 

63 

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 ] 

69 

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] = "" 

74 

75 apt_pkg.parse_commandline(Cnf, Arguments, sys.argv) 

76 

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() 

80 

81 session = DBConn().session() 

82 

83 if not keyrings: 

84 keyrings = get_active_keyring_paths() 

85 

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(" ", "") 

109 

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) 

128 

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)) 

136 

137 print( 

138 "0x%s -> %s <%s> -> %s -> %s" 

139 % (Cnf["Add-User::Options::Key"], name, emails[0], uid, primary_key) 

140 ) 

141 

142 prompt = "Add user %s with above data (y/N) ? " % (uid) 

143 yn = utils.input_or_exit(prompt).lower() 

144 

145 if yn == "y": 

146 # Create an account for the user? 

147 summary = "" 

148 

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() 

154 

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") 

160 

161 print( 

162 "Added:\nUid:\t %s (ID: %s)\nMaint:\t %s\nFP:\t %s" 

163 % (uid, uid_id, name, primary_key) 

164 ) 

165 

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) 

183 

184 else: 

185 uid = None 

186 

187 

188####################################################################################### 

189 

190 

191if __name__ == "__main__": 

192 main()