1 |
tomk 13/02/24 13:07:47 |
2 |
|
3 |
Added: retire-dev-forums.pl |
4 |
Log: |
5 |
Script to retire devs on the forums |
6 |
|
7 |
Revision Changes Path |
8 |
1.1 forums/scripts/retire-dev-forums.pl |
9 |
|
10 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/forums/scripts/retire-dev-forums.pl?rev=1.1&view=markup |
11 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/forums/scripts/retire-dev-forums.pl?rev=1.1&content-type=text/plain |
12 |
|
13 |
Index: retire-dev-forums.pl |
14 |
=================================================================== |
15 |
#!/usr/bin/perl |
16 |
|
17 |
# ----------------------------------------------------------------------------- |
18 |
# |
19 |
# retire-dev-forums.pl |
20 |
# |
21 |
# date : 2013-02-18 |
22 |
# copyright : Tom Knight <tomk@g.o> |
23 |
# version : 0.1 |
24 |
# license : GPL2 |
25 |
# description : This script retires developers from the forums. |
26 |
# return code : 0 on success, 1 on error, 2 on success but with action required by forums staff. |
27 |
# |
28 |
# ----------------------------------------------------------------------------- |
29 |
# |
30 |
# This program is free software; you can redistribute it and/or modify it under |
31 |
# the terms of the GNU General Public License as published by the Free Software |
32 |
# Foundation; either version 2 of the License, or (at your option) any later |
33 |
# version. |
34 |
# |
35 |
# ----------------------------------------------------------------------------- |
36 |
|
37 |
use warnings; |
38 |
use strict; |
39 |
use DBI; |
40 |
use File::Basename; |
41 |
use Net::LDAP; |
42 |
use Net::LDAP::Util qw(ldap_error_text); |
43 |
|
44 |
my $DEBUG = 0; |
45 |
#my $DEBUG = 1; |
46 |
my $PRETEND = 0; |
47 |
#my $PRETEND = 1; |
48 |
|
49 |
my $LDAP_SERVER = "ldap://ldap1.gentoo.org"; |
50 |
my $LDAP_BASEDN = "dc=gentoo, dc=org"; |
51 |
|
52 |
my $RANK_ADMIN = 1; |
53 |
my $RANK_MOD = 3; |
54 |
my $RANK_DEV = 9; |
55 |
my $RANK_BODHISATTVA = 14; |
56 |
my $RANK_RETIRED_DEV = 15; |
57 |
|
58 |
my $LEVEL_ADMIN = 1; |
59 |
my $LEVEL_MOD = 2; |
60 |
my $LEVEL_USER = 0; |
61 |
|
62 |
my $GROUP_DEVS = 24; |
63 |
my $GROUP_GLOBAL_MODS = 916; |
64 |
my $GROUP_MODS = 970; |
65 |
my $GROUP_BODHISATTVA = 10770; |
66 |
|
67 |
my $EXIT_SUCCESS = 0; |
68 |
my $EXIT_ERROR = 1; |
69 |
my $EXIT_NOTIFY = 2; |
70 |
|
71 |
#my $connect_string = "DBI:mysql:;mysql_read_default_file=~/.my.cnf;mysql_read_default_group=testforum_rw"; |
72 |
my $connect_string = "DBI:mysql:;mysql_read_default_file=~/.my.cnf;mysql_read_default_group=forum_rw"; |
73 |
|
74 |
my $username; |
75 |
|
76 |
my $user_id; |
77 |
|
78 |
my $mail; |
79 |
|
80 |
my $sql; |
81 |
|
82 |
my $user_ref; |
83 |
my $users_ref; |
84 |
|
85 |
my $new_rank; |
86 |
my $new_email; |
87 |
my $new_level; |
88 |
|
89 |
my $make_includes = 0; |
90 |
|
91 |
my $dbh; |
92 |
|
93 |
my @rows; |
94 |
my $count; |
95 |
|
96 |
my $ldap; |
97 |
my $msg; |
98 |
my $filter; |
99 |
my @attrs; |
100 |
|
101 |
if (@ARGV != 1) { |
102 |
quit($dbh, $EXIT_ERROR, "usage: " . basename($0) . " username\n"); |
103 |
} |
104 |
|
105 |
$username = $ARGV[0]; |
106 |
|
107 |
# get forumsUID, mail from LDAP based on passed in username |
108 |
|
109 |
$ldap = Net::LDAP->new($LDAP_SERVER, version => 3, onerror => "die") || die "Connection Failed"; |
110 |
|
111 |
$msg = $ldap->start_tls(verify => 'required', |
112 |
clientcert => '/etc/openldap/ssl/star.gentoo.org.crt', |
113 |
clientkey => '/etc/openldap/ssl/star.gentoo.org.key', |
114 |
cafile => '/etc/openldap/ssl/ca.pem'); |
115 |
|
116 |
if ($msg->is_error) { |
117 |
die ldap_error_text($msg->code); |
118 |
} |
119 |
|
120 |
$msg = $ldap->bind; |
121 |
|
122 |
if ($msg->is_error) { |
123 |
die ldap_error_text($msg->code); |
124 |
} |
125 |
|
126 |
$filter = "(uid=$username)"; |
127 |
|
128 |
$msg = $ldap->search(filter => $filter, base => $LDAP_BASEDN, attrs => ['forumsUID', 'mail']); |
129 |
|
130 |
if ($msg->is_error) { |
131 |
die ldap_error_text($msg->code); |
132 |
} |
133 |
|
134 |
foreach my $entry ($msg->entries) { |
135 |
@attrs = $entry->attributes; |
136 |
|
137 |
foreach my $attr (@attrs) { |
138 |
foreach my $val (@{$entry->get_value($attr, asref => 1)}) { |
139 |
if ($attr eq "forumsUID") { |
140 |
$user_id = $val; |
141 |
last; |
142 |
} elsif ($attr eq "mail" && $val !~ /\@gentoo\.org$/) { |
143 |
$mail = $val; |
144 |
last; |
145 |
} |
146 |
} |
147 |
} |
148 |
} |
149 |
|
150 |
# if forumsUID is not set, exit |
151 |
if (!defined $user_id) { |
152 |
quit($dbh, $EXIT_SUCCESS, "forumsUID not set in LDAP for $username - nothing left to do\n"); |
153 |
} |
154 |
|
155 |
# connect to DB and begin transaction |
156 |
$dbh = DBI->connect($connect_string, '', '', { RaiseError => 1, AutoCommit => 0 } ) || die("Could not connect to database!"); |
157 |
|
158 |
$sql = "SELECT user_id, username, user_level, user_rank, user_email FROM phpbb_users WHERE user_id = $user_id;"; |
159 |
|
160 |
$users_ref = execute_sql_select_hashref($dbh, $sql, "user_id"); |
161 |
|
162 |
# check we have a user |
163 |
|
164 |
if (%{$users_ref}) { |
165 |
$user_ref = $users_ref->{$user_id}; |
166 |
} else { |
167 |
quit($dbh, $EXIT_ERROR, "forums user not found for user_id $user_id\n"); |
168 |
} |
169 |
|
170 |
# username might be different on the forums |
171 |
|
172 |
$username = get_username($username, $user_ref->{'username'}); |
173 |
|
174 |
# user rank |
175 |
|
176 |
if ($user_ref->{'user_rank'} == $RANK_ADMIN || $user_ref->{'user_rank'} == $RANK_MOD) { |
177 |
$new_rank = $RANK_BODHISATTVA; |
178 |
} elsif ($user_ref->{'user_rank'} == $RANK_DEV) { |
179 |
$new_rank = $RANK_RETIRED_DEV; |
180 |
} else { |
181 |
# they already have the correct rank |
182 |
$new_rank = $user_ref->{'user_rank'}; |
183 |
} |
184 |
|
185 |
# user level |
186 |
|
187 |
if ($user_ref->{'user_level'} == $LEVEL_ADMIN || $user_ref->{'user_level'} == $LEVEL_MOD) { |
188 |
$new_level = $LEVEL_USER; |
189 |
$make_includes = 1; |
190 |
} else { |
191 |
# they already have the correct level |
192 |
$new_level = $user_ref->{'user_level'}; |
193 |
} |
194 |
|
195 |
# user e-mail |
196 |
$new_email = $user_ref->{'user_email'}; |
197 |
|
198 |
if ($user_ref->{'user_email'} =~ '@gentoo\.org$' && defined $mail) { |
199 |
# set to alternative mail from LDAP if we have it |
200 |
|
201 |
$new_email = $mail; |
202 |
} |
203 |
|
204 |
# user groups |
205 |
|
206 |
$sql = "SELECT COUNT(*) FROM phpbb_groups WHERE group_moderator = $user_id;"; |
207 |
@rows = execute_sql_select($dbh, $sql); |
208 |
$count = $rows[0]; |
209 |
|
210 |
if ($count > 0) { |
211 |
# poke f-mods |
212 |
quit($dbh, $EXIT_NOTIFY, "$username is a group moderator for $count groups\n$username cannot be automatically retired, notify #gentoo-forums on freenode or forum-mods\@gentoo.org\n"); |
213 |
} |
214 |
|
215 |
print "deleting $username from groups\n"; |
216 |
|
217 |
$sql = "DELETE FROM phpbb_user_group WHERE group_id = $GROUP_DEVS AND user_id = $user_id;"; |
218 |
$count = execute_sql($dbh, $sql); |
219 |
|
220 |
if ($DEBUG) { |
221 |
if ($count > 0) { |
222 |
print "deleted $username from Developers group\n"; |
223 |
} else { |
224 |
print "$username not found in Developers group\n"; |
225 |
} |
226 |
} |
227 |
|
228 |
$sql = "DELETE FROM phpbb_user_group WHERE group_id = $GROUP_GLOBAL_MODS AND user_id = $user_id;"; |
229 |
$count = execute_sql($dbh, $sql); |
230 |
|
231 |
if ($DEBUG) { |
232 |
if ($count > 0) { |
233 |
print "deleted $username from Global Moderators group\n"; |
234 |
} else { |
235 |
print "$username not found in Global Moderators group\n"; |
236 |
} |
237 |
} |
238 |
|
239 |
$sql = "DELETE FROM phpbb_user_group WHERE group_id = $GROUP_MODS AND user_id = $user_id;"; |
240 |
$count = execute_sql($dbh, $sql); |
241 |
|
242 |
if ($DEBUG) { |
243 |
if ($count > 0) { |
244 |
print "deleted $username from Moderators group\n"; |
245 |
} else { |
246 |
print "$username not found in Moderators group\n"; |
247 |
} |
248 |
} |
249 |
|
250 |
if ($make_includes) { |
251 |
# user was a moderator/admin so add to Bodhisattva group |
252 |
$sql = "SELECT COUNT(*) FROM phpbb_user_group WHERE group_id = $GROUP_BODHISATTVA AND user_id = $user_id;"; |
253 |
@rows = execute_sql_select($dbh, $sql); |
254 |
$count = $rows[0]; |
255 |
|
256 |
if ($count == 0) { |
257 |
$sql = "INSERT INTO phpbb_user_group SET group_id = $GROUP_BODHISATTVA, user_id = $user_id, user_pending = 0;"; |
258 |
execute_sql($dbh, $sql); |
259 |
} |
260 |
} |
261 |
|
262 |
# permissions |
263 |
|
264 |
# If the user has been given individual permissions, this will be through their personal group |
265 |
|
266 |
$sql = "SELECT group_id FROM phpbb_auth_access aa |
267 |
LEFT JOIN phpbb_groups g USING (group_id) |
268 |
LEFT JOIN phpbb_user_group ug USING (group_id) |
269 |
WHERE ug.user_id = $user_id |
270 |
AND g.group_single_user = 1;"; |
271 |
|
272 |
# if there are any then delete them from phpbb_auth_access |
273 |
my @groups = execute_sql_select($dbh, $sql); |
274 |
|
275 |
if (@groups) { |
276 |
print "deleting forum permissions for $username\n"; |
277 |
|
278 |
foreach my $group (@groups) { |
279 |
$sql = "DELETE FROM phpbb_auth_access WHERE group_id = $group;"; |
280 |
|
281 |
$count = execute_sql($dbh, $sql); |
282 |
|
283 |
if ($DEBUG) { |
284 |
if ($count > 0) { |
285 |
print "deleting $username permissions for group $group\n"; |
286 |
} else { |
287 |
print "group $group not found in permissions table\n"; |
288 |
} |
289 |
} |
290 |
} |
291 |
} |
292 |
|
293 |
print "updating forums status for $username\n"; |
294 |
|
295 |
# update user |
296 |
|
297 |
$sql = "UPDATE phpbb_users SET user_rank = $new_rank, user_level = $new_level, user_email = '$new_email' WHERE user_id = $user_id;"; |
298 |
|
299 |
execute_sql($dbh, $sql); |
300 |
|
301 |
# make includes |
302 |
if ($make_includes) { |
303 |
# poke f-mods |
304 |
quit($dbh, $EXIT_NOTIFY, "$username was a forums moderator - so the forums 'make includes' function needs to be run\nnotify #gentoo-forums on freenode or forum-mods\@gentoo.org\n"); |
305 |
} |
306 |
|
307 |
quit($dbh, $EXIT_SUCCESS, "done"); |
308 |
|
309 |
sub execute_sql { |
310 |
my $dbh = shift; |
311 |
my $sql = shift; |
312 |
|
313 |
my $rows = -1; |
314 |
my $sth; |
315 |
|
316 |
if ($DEBUG) { |
317 |
print "" . (caller(0))[3] . ": $sql\n"; |
318 |
} |
319 |
|
320 |
if (!$PRETEND) { |
321 |
|
322 |
$sth = $dbh->prepare("$sql"); |
323 |
$rows = $sth->execute(); |
324 |
} |
325 |
|
326 |
return $rows; |
327 |
} |
328 |
|
329 |
sub execute_sql_select { |
330 |
my $dbh = shift; |
331 |
my $sql = shift; |
332 |
|
333 |
my @read_data = (); |
334 |
my @return_values = (); |
335 |
my $sth; |
336 |
|
337 |
if ($DEBUG) { |
338 |
print "" . (caller(0))[3] . ": $sql\n"; |
339 |
} |
340 |
|
341 |
$sth = $dbh->prepare("$sql"); |
342 |
$sth->execute(); |
343 |
while (@read_data = $sth->fetchrow_array()) { |
344 |
push (@return_values, @read_data); |
345 |
} |
346 |
|
347 |
return @return_values; |
348 |
} |
349 |
|
350 |
sub execute_sql_select_hashref { |
351 |
my $dbh = shift; |
352 |
my $sql = shift; |
353 |
my $key_field = shift; |
354 |
|
355 |
my $return_values_ref; |
356 |
|
357 |
if ($DEBUG) { |
358 |
print "" . (caller(0))[3] . ": $sql\n"; |
359 |
} |
360 |
|
361 |
$return_values_ref = $dbh->selectall_hashref($sql, $key_field); |
362 |
|
363 |
return $return_values_ref; |
364 |
} |
365 |
|
366 |
sub get_username { |
367 |
my $gentoo_username = shift; |
368 |
my $forums_username = shift; |
369 |
|
370 |
if ($gentoo_username ne $forums_username) { |
371 |
return $gentoo_username . " (forums username $forums_username)"; |
372 |
} |
373 |
|
374 |
return $gentoo_username; |
375 |
} |
376 |
|
377 |
sub quit { |
378 |
my $dbh = shift; |
379 |
my $return_code = shift; |
380 |
my $message = shift; |
381 |
|
382 |
# commit or rollback |
383 |
if (defined $dbh) { |
384 |
if ($return_code == $EXIT_SUCCESS || $return_code == $EXIT_NOTIFY) { |
385 |
if ($DEBUG) { |
386 |
print "committing tranaction\n"; |
387 |
} |
388 |
$dbh->commit(); |
389 |
} elsif ($return_code == $EXIT_ERROR) { |
390 |
if ($DEBUG) { |
391 |
print "rolling back tranaction\n"; |
392 |
} |
393 |
$dbh->rollback(); |
394 |
} |
395 |
|
396 |
$dbh->disconnect(); |
397 |
} |
398 |
|
399 |
if (defined $message) { |
400 |
print {$return_code ? *STDOUT : *STDERR} $message; |
401 |
} |
402 |
|
403 |
exit $return_code; |
404 |
} |