10 config
= configparser
.RawConfigParser()
11 config
.read(os
.path
.dirname(os
.path
.realpath(__file__
)) + "/../conf/config")
13 aur_db_host
= config
.get('database', 'host')
14 aur_db_name
= config
.get('database', 'name')
15 aur_db_user
= config
.get('database', 'user')
16 aur_db_pass
= config
.get('database', 'password')
17 aur_db_socket
= config
.get('database', 'socket')
19 repo_path
= config
.get('serve', 'repo-path')
20 repo_regex
= config
.get('serve', 'repo-regex')
21 git_shell_cmd
= config
.get('serve', 'git-shell-cmd')
22 git_update_cmd
= config
.get('serve', 'git-update-cmd')
23 ssh_cmdline
= config
.get('serve', 'ssh-cmdline')
25 enable_maintenance
= config
.getboolean('options', 'enable-maintenance')
26 maintenance_exc
= config
.get('options', 'maintenance-exceptions').split()
29 def pkgbase_from_name(pkgbase
):
30 db
= mysql
.connector
.connect(host
=aur_db_host
, user
=aur_db_user
,
31 passwd
=aur_db_pass
, db
=aur_db_name
,
32 unix_socket
=aur_db_socket
)
34 cur
.execute("SELECT ID FROM PackageBases WHERE Name = %s", [pkgbase
])
38 return row
[0] if row
else None
41 def pkgbase_exists(pkgbase
):
42 return pkgbase_from_name(pkgbase
) is not None
46 db
= mysql
.connector
.connect(host
=aur_db_host
, user
=aur_db_user
,
47 passwd
=aur_db_pass
, db
=aur_db_name
,
48 unix_socket
=aur_db_socket
)
51 cur
.execute("SELECT ID FROM Users WHERE Username = %s ", [user
])
52 userid
= cur
.fetchone()[0]
54 die('{:s}: unknown user: {:s}'.format(action
, user
))
56 cur
.execute("SELECT Name, PackagerUID FROM PackageBases " +
57 "WHERE MaintainerUID = %s ", [userid
])
59 print((' ' if row
[1] else '*') + row
[0])
63 def create_pkgbase(pkgbase
, user
):
64 if not re
.match(repo_regex
, pkgbase
):
65 die('{:s}: invalid repository name: {:s}'.format(action
, pkgbase
))
66 if pkgbase_exists(pkgbase
):
67 die('{:s}: package base already exists: {:s}'.format(action
, pkgbase
))
69 db
= mysql
.connector
.connect(host
=aur_db_host
, user
=aur_db_user
,
70 passwd
=aur_db_pass
, db
=aur_db_name
,
71 unix_socket
=aur_db_socket
)
74 cur
.execute("SELECT ID FROM Users WHERE Username = %s ", [user
])
75 userid
= cur
.fetchone()[0]
77 die('{:s}: unknown user: {:s}'.format(action
, user
))
79 cur
.execute("INSERT INTO PackageBases (Name, SubmittedTS, ModifiedTS, " +
80 "SubmitterUID, MaintainerUID) VALUES (%s, UNIX_TIMESTAMP(), " +
81 "UNIX_TIMESTAMP(), %s, %s)", [pkgbase
, userid
, userid
])
82 pkgbase_id
= cur
.lastrowid
84 cur
.execute("INSERT INTO PackageNotifications (PackageBaseID, UserID) " +
85 "VALUES (%s, %s)", [pkgbase_id
, userid
])
91 def pkgbase_set_keywords(pkgbase
, keywords
):
92 pkgbase_id
= pkgbase_from_name(pkgbase
)
94 die('{:s}: package base not found: {:s}'.format(action
, pkgbase
))
96 db
= mysql
.connector
.connect(host
=aur_db_host
, user
=aur_db_user
,
97 passwd
=aur_db_pass
, db
=aur_db_name
,
98 unix_socket
=aur_db_socket
)
101 cur
.execute("DELETE FROM PackageKeywords WHERE PackageBaseID = %s",
103 for keyword
in keywords
:
104 cur
.execute("INSERT INTO PackageKeywords (PackageBaseID, Keyword) "
105 "VALUES (%s, %s)", [pkgbase_id
, keyword
])
111 def pkgbase_has_write_access(pkgbase
, user
):
112 db
= mysql
.connector
.connect(host
=aur_db_host
, user
=aur_db_user
,
113 passwd
=aur_db_pass
, db
=aur_db_name
,
114 unix_socket
=aur_db_socket
, buffered
=True)
117 cur
.execute("SELECT COUNT(*) FROM PackageBases " +
118 "LEFT JOIN PackageComaintainers " +
119 "ON PackageComaintainers.PackageBaseID = PackageBases.ID " +
120 "INNER JOIN Users ON Users.ID = PackageBases.MaintainerUID " +
121 "OR PackageBases.MaintainerUID IS NULL " +
122 "OR Users.ID = PackageComaintainers.UsersID " +
123 "WHERE Name = %s AND Username = %s", [pkgbase
, user
])
124 return cur
.fetchone()[0] > 0
128 sys
.stderr
.write("{:s}\n".format(msg
))
132 def die_with_help(msg
):
133 die(msg
+ "\nTry `{:s} help` for a list of commands.".format(ssh_cmdline
))
136 user
= os
.environ
.get('AUR_USER')
137 privileged
= (os
.environ
.get('AUR_PRIVILEGED', '0') == '1')
138 ssh_cmd
= os
.environ
.get('SSH_ORIGINAL_COMMAND')
139 ssh_client
= os
.environ
.get('SSH_CLIENT')
142 die_with_help("Interactive shell is disabled.")
143 cmdargv
= shlex
.split(ssh_cmd
)
145 remote_addr
= ssh_client
.split(' ')[0] if ssh_client
else None
147 if enable_maintenance
:
148 if remote_addr
not in maintenance_exc
:
149 die("The AUR is down due to maintenance. We will be back soon.")
151 if action
== 'git-upload-pack' or action
== 'git-receive-pack':
153 die_with_help("{:s}: missing path".format(action
))
155 path
= cmdargv
[1].rstrip('/')
156 if not path
.startswith('/'):
158 if not path
.endswith('.git'):
161 if not re
.match(repo_regex
, pkgbase
):
162 die('{:s}: invalid repository name: {:s}'.format(action
, pkgbase
))
164 if not pkgbase_exists(pkgbase
):
165 create_pkgbase(pkgbase
, user
)
167 if action
== 'git-receive-pack':
168 if not privileged
and not pkgbase_has_write_access(pkgbase
, user
):
169 die('{:s}: permission denied: {:s}'.format(action
, user
))
171 os
.environ
["AUR_USER"] = user
172 os
.environ
["AUR_PKGBASE"] = pkgbase
173 os
.environ
["GIT_NAMESPACE"] = pkgbase
174 cmd
= action
+ " '" + repo_path
+ "'"
175 os
.execl(git_shell_cmd
, git_shell_cmd
, '-c', cmd
)
176 elif action
== 'set-keywords':
178 die_with_help("{:s}: missing repository name".format(action
))
179 pkgbase_set_keywords(cmdargv
[1], cmdargv
[2:])
180 elif action
== 'list-repos':
182 die_with_help("{:s}: too many arguments".format(action
))
184 elif action
== 'setup-repo':
186 die_with_help("{:s}: missing repository name".format(action
))
188 die_with_help("{:s}: too many arguments".format(action
))
189 create_pkgbase(cmdargv
[1], user
)
190 elif action
== 'restore':
192 die_with_help("{:s}: missing repository name".format(action
))
194 die_with_help("{:s}: too many arguments".format(action
))
197 if not re
.match(repo_regex
, pkgbase
):
198 die('{:s}: invalid repository name: {:s}'.format(action
, pkgbase
))
200 if pkgbase_exists(pkgbase
):
201 die('{:s}: package base exists: {:s}'.format(action
, pkgbase
))
202 create_pkgbase(pkgbase
, user
)
204 os
.environ
["AUR_USER"] = user
205 os
.environ
["AUR_PKGBASE"] = pkgbase
206 os
.execl(git_update_cmd
, git_update_cmd
, 'restore')
207 elif action
== 'help':
209 " help Show this help message and exit.\n" +
210 " list-repos List all your repositories.\n" +
211 " restore <name> Restore a deleted package base.\n" +
212 " set-keywords <name> [...] Change package base keywords.\n" +
213 " setup-repo <name> Create an empty repository.\n" +
214 " git-receive-pack Internal command used with Git.\n" +
215 " git-upload-pack Internal command used with Git.")
217 die_with_help("invalid command: {:s}".format(action
))