#!/usr/bin/env perl # delete_joomla_users.pl # # Delete all Joomla users from a Joomla site (less a list of users to be kept) # # Copyright (C) 2015 Bradley Dean # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation, either version 3 of the License, or (at your option) any later # version. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this program. If not, see . # This script is written with a bunch of manually configured # values rather than configuring this with command-line options # as the script isn't meant to be used very often! use strict; use warnings; ############################################################ # Don't do anything unless this is commented out # (ie don't run this script unless you mean it) die "Script Disabled - aborting"; ############################################################ # Modules use Data::Dumper; use WWW::Mechanize; ############################################################ # Configuration # # autoflush stdout $| = 1; # These id's should never be deleted: my @keep_user_ids = qw(); die( "You need to add your wanted user ids to \@keep_user_ids - " . "otherwise this script would delete all users including " . "all administrators and super users." ) unless ( @keep_user_ids ); # The number of users to list and delete at a time my $list_limit = 500; ### Add a Joomla Super User username and password here my $ua = WWW::Mechanize->new(); $ua->credentials( # /administrator/ username: "", # /administrator/ password: "", ); ### The /administrator/ URL for your Joomla site my $admin_base_url = q{}; die "Must configure a base URL" unless $admin_base_url; ############################################################ # Main Script # # Start at login page $ua->get($admin_base_url); $ua->submit_form( form_number => 0, fields => { # joomla superuser username: username => '', # joomla superuser passowrd: passwd => '', } ); set_user_list_limit($ua, $list_limit); # Reload the users page over and over again while ( 1 ) { my $delete_count = delete_users($ua); print "Users deleted: ${delete_count}\n"; if ( $delete_count < 1 ) { print "No more users to delete, done!\n"; exit 0; } sleep 5; } # Find the md5sum session hidden form field sub get_md5_hidden_input { my ($ua) = @_; my $md5_hidden_input; for my $form ( $ua->forms ) { for my $input ( $form->inputs ) { if ( $input->type eq 'hidden' && $input->name =~ /^[a-f0-9]{32}$/ && $input->value eq "1" ) { $md5_hidden_input = $input; } } } if ( ! $md5_hidden_input ) { die "No MD5 hidden field found"; } return $md5_hidden_input; } # Set the user list limit sub set_user_list_limit { my ($ua, $limit) = @_; $ua->follow_link( text => 'User Manager', n => 1, ); my $md5_hidden_input = get_md5_hidden_input($ua); $ua->post( qq{${admin_base_url}/index.php?option=com_users&view=users}, { 'task' => '', $md5_hidden_input->name() => $md5_hidden_input->value(), 'list[limit]' => $limit, } ); } # Delete a batch of users - returns the count of users to be deleted sub delete_users { my ($ua) = @_; $ua->follow_link( text => 'User Manager', n => 1, ); my $md5_hidden_input = get_md5_hidden_input($ua); $ua->follow_link( text => 'User Manager', n => 1, ); # Find the cid[] fields to get the user ids my @user_ids; for my $form ( $ua->forms ) { for my $input ( $form->inputs ) { if ( $input->isa('HTML::Form::ListInput') && $input->name eq 'cid[]' ) { for my $value ( $input->possible_values ) { # User ids are integers, skip those ids in the # @keep_user_ids array if ( $value && $value =~ /^\d+$/ && ! grep { $_ == $value } @keep_user_ids ) { push @user_ids, $value; } } } } } # print Dumper($ua->forms); # Now we have enough information to build our own delete #print Dumper($md5_hidden_input); #print Dumper(\@user_ids); if ( @user_ids == 0 ) { # No users left, return return 0; } print "Deleting users: " . join(", ", @user_ids) . "\n"; $ua->post( qq{${admin_base_url}/index.php?option=com_users&view=users}, { 'task' => 'users.delete', $md5_hidden_input->name() => $md5_hidden_input->value(), 'cid[]' => \@user_ids, } ); return scalar(@user_ids); }