1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
|
#!/usr/bin/perl
=head1 NAME
user-simple-admin - Example script to administer a User::Simple database
=head1 SYNOPSIS
What you always have to specify:
- How to get to the information: a DSN (--dsn), the table name (--tbl),
and probably the database user (--dbuser) and password (--dbpass)
- An action to perform: --new_user, --mod_user, --remove_user
- The attributes needed for your query (--login, --name, --level, --password)
- Optionally, to get a listing of the users in the database, use --dump_users
Table creation:
user-simple-admin --dsn 'dbi:Pg:dbname=database;host=some.host.org'
--table user_simple --dbuser useradmin --dbpass s3kr3t --create_plain
user-simple-admin --dsn 'dbi:Pg:dbname=database;host=some.host.org'
--table user_simple --dbuser useradmin --dbpass s3kr3t --create_rdbms
User creation example:
user-simple-admin --dsn 'dbi:Pg:dbname=database;host=some.host.org'
--table user_simple --dbuser useradmin --dbpass s3kr3t --new_user
--login joe --name 'Joe Schmoe' --passwd mys3kr17 --level 5
User remotion:
user-simple-admin --dsn 'dbi:Pg:dbname=database;host=some.host.org'
--table user_simple--dbuser useradmin --dbpass s3kr3t --remove_user
--login john
User modification:
user-simple-admin --dsn 'dbi:Pg:dbname=database;host=some.host.org'
--table user_simple --dbuser useradmin --dbpass s3kr3t --new_user
--login joe --name 'Joe A. Schmoe' --passwd dont_forget_it --level 2
=head1 DESCRIPTION
This script gives you access from the command line to the main
User::Simple::Admin functionality. Please note that it has been written more as
an example than as a script you will use in your day to day administration -
But if it suits you, well... :)
The script is made to be run non-interactively, taking all of its input via the
command line (using the standard L<Getopts::Long> syntax), and signalling
either success or failure as the exit code (as always, 0 means success, and any
other thing means failure).
About the L<Getopts::Long> syntax, in a nutshell: You can specify the options
to the script in any order, as long as you keep the switches next to their
values (that is, C<--tbl tablename --dump_users> is the same as C<--dump_users
--tbl tablename>, but it is not the same as C<--tbl --dump_users tablename>.
You can use the shortest possible not ambiguous string for each of the switches
(i.e. C<--remove_user> is equivalent to C<--r>).
First of all, you have to get the script to get to the users' data - In
order to do so, you have to specify a DSN (a DBI Data Source Name - A bit
obscure, yes, I should replace it to something more intuitive as soon as I have
some time to do so) and the name of the table where the information is located.
This should be done with the C<--dsn> and C<--tbl> options. Probably you will
also specify a database user name and password - do so using the C<--dbuser>
and C<--dbpass> options.
=head2 Table creation
If you specify C<--create_plain> or C<--create_rdbms>, the User::Admin::Simple
object will be instantiated by creating (instead of just accessing) the
specified table. Beware, as attempting to create an already existing table will
not work!
C<--create_rdbms> should be used whenever possible (this is, whenever you are
using a real RDBMS behind User::Simple, in contraposition to a simple
file-based structure such as DBD::XBase, DBD::CSV or similar ones). If you are
using a file-based structure, use C<--create_plain> instead. For further
details, refer to the L<User::Simple::Admin> manual.
=head2 User creation
To create a new user, specify C<--new_user> and give the desired user
information - The only required option is C<--login>, as it is the unique
descriptor for this user - The other available switches are C<--name>,
C<--passwd> and C<--level>. Again, refer to L<User::Simple::Admin> for further
details.
If you do not specify a password upon user creation, the account will be
created but access to it will be disabled until a password is set.
=head2 User remotion
Use C<--remove_user>. You have to specify the C<--login> you will be removing -
Don't specify any other data; the script will refuse to work if you specify
any of the other data options.
=head2 User modification
Use C<--mod_user>. You need to specify the C<--login> you are referring to.
You cannot change a user's login, it is an immutable field. You can specify
one or more of the C<--name>, C<--passwd> and C<--level> data options.
=head2 Querying
If you specify C<--dump_users>, a user listing will be returned to you. Please
note that you can ask for C<--dump_users> when performing other opertions (i.e.
creation, remotion) - It will be run as the last operation, however, if the
operation fails, the users list will not be dumped.
=head2 Other switches
C<--quiet> supresses all output (including errors produced by this script, the
errors generated by User::Simple::Admin, DBI or whatever else will still be
sent) - Only the users dump will be printed.
C<--verbose> will give status debug information you will very seldom require.
=head2 Examples
Create a table in a remote PostgreSQL database and insert a user in it:
user-simple-admin --dsn 'dbi:Pg:dbname=userdb;host=dbserver' --dbuser dbadmin --dbpass dbs3kr37 --tbl test --create_rdbms --new_user --login someone --name 'A random user'
Change that user's password in order to enable the account
user-simple-admin --dsn 'dbi:Pg:dbname=userdb;host=dbserver' --dbuser dbadmin --dbpass dbs3kr37 --tbl test --mod_user --login someone --passwd thepassword
Remove that user
user-simple-admin --dsn 'dbi:Pg:dbname=userdb;host=dbserver' --dbuser dbadmin --dbpass dbs3kr37 --tbl test --remove_user --login someone
Get the users listing in a DBD::XBase database
user-simple-admin --dsn 'dbi:XBase:/home/user/databases/users' --tbl user_simple --dump_users
=head1 DEPENDS ON
L<DBI> (and a suitable L<DBD> backend)
L<Getopt::Long>
L<User::Simple::Admin>
=head1 SEE ALSO
L<User::Simple> and L<User::Simple::Admin>
=head1 AUTHOR
Gunnar Wolf <gwolf@gwolf.org>
=head1 COPYRIGHT
Copyright 2005 Gunnar Wolf / Instituto de Investigaciones Económicas UNAM
This module is Free Software, it can be redistributed under the same terms
as Perl.
=cut
use lib qw(/home/gwolf/User-Simple/lib);
use strict;
use warnings;
use Carp;
use DBI;
use Getopt::Long;
use User::Simple::Admin;
my (%conf, $db, $ua);
# Default values, to be overwritten by Getopt::Long
%conf = ( dsn => 'DBI:XBase:/tmp/user_simple',
dbtable => 'user_simple',
dbuser => undef,
dbpass => undef,
verbose => 1,
create_plain => undef,
create_rdbms => undef,
new_user => undef,
remove_user => undef,
mod_user => undef,
login => undef,
passwd => undef,
name => undef,
level => undef
);
GetOptions ('dsn=s' => \$conf{dsn},
'tbl=s' => \$conf{dbtable},
'dbuser=s' => \$conf{dbuser},
'dbpass=s' => \$conf{dbpass},
'create_plain' => \$conf{create_plain},
'create_rdbms' => \$conf{create_rdbms},
'dump_users' => \$conf{dump_users},
'new_user' => \$conf{new_user},
'remove_user' => \$conf{remove_user},
'mod_user' => \$conf{mod_user},
'login=s' => \$conf{login},
'passwd=s' => \$conf{passwd},
'name=s' => \$conf{name},
'level=i' => \$conf{level},
'quiet' => sub {$conf{verbose} = 0},
'verbose' => sub {$conf{verbose} = 2}
) || usage_err();
debug(2,'Options parsed correctly');
#use Data::Dumper; warn Dumper \%conf;
# Check we are requested to carry out at least one operation - Finish
# otherwise. Check as well for mutually exclusive options
usage_err() unless (# Operations
$conf{create_plain} or $conf{create_rdbms} or
$conf{new_user} or $conf{remove_user} or
$conf{mod_user} or $conf{dump_users} or
# Mutually exclusive
($conf{create_plain} and $conf{create_rdbms}) or
($conf{new_user} and $conf{remove_user}) or
($conf{new_user} and $conf{mod_user}) or
($conf{mod_user} and $conf{remove_user})
);
# Connect to the DB
$db = DBI->connect($conf{dsn},$conf{dbuser},$conf{dbpass},{AutoCommit => 1});
ref($db) or dbconn_err();
debug(2,'Database connection established');
# get a User::Simple::Admin instance (creating the structure if we were
# requested to)
if ($conf{create_rdbms}) {
$ua = User::Simple::Admin->create_rdbms_db_structure($db, $conf{dbtable});
} elsif ($conf{create_plain}) {
$ua = User::Simple::Admin->create_plain_db_structure($db, $conf{dbtable});
} else {
$ua = User::Simple::Admin->new($db, $conf{dbtable});
}
ref($ua) or useradmin_err();
debug(2,'User::Simple::Admin instance established');
# Ok, everything is now ready - Do what we were told to do!
new_user() if $conf{new_user};
remove_user() if $conf{remove_user};
mod_user() if $conf{mod_user};
dump_users() if $conf{dump_users};
debug(2,'Program finished successfully');
exit 0;
sub new_user {
# For new user creation, we only require a login
usage_err() unless $conf{login};
unless ($ua->new_user($conf{login}, $conf{name},
$conf{passwd}, $conf{level})) {
newuser_err();
}
}
sub remove_user {
# For user remotion, we require a login - But name, password and level
# should not be specified.
my ($id);
usage_err() if ($conf{name} or $conf{passwd} or $conf{level});
$id = $ua->id($conf{login}) or no_user_err();
$ua->remove_user($id) or remove_err();
}
sub mod_user {
# For user modification, we require at least one of name, password and
# level - and we require login _not_ to be set.
my ($id);
usage_err() unless ($conf{name} or $conf{passwd} or $conf{level} or
!$conf{login});
$id = $ua->id($conf{login}) or no_user_err();
if (defined $conf{name}) {
$ua->set_name($id, $conf{name}) or mod_err();
}
if (defined $conf{level}) {
$ua->set_level($id, $conf{level}) or mod_err();
}
if (defined $conf{passwd}) {
$ua->set_passwd($id, $conf{passwd}) or mod_err();
}
}
sub dump_users {
my %users = $ua->dump_users;
# Print the header first
printf("%-4s %-15s %-30s %-5s\n", 'ID', 'Login', 'Name', 'Level');
print '='x60,"\n";
for my $user (sort {$a<=>$b} keys %users) {
printf("%4d %-15s %-30s %5d\n", $user, $users{$user}{login},
$users{$user}{name}, $users{$user}{level});
}
}
sub usage_err {
my $progname = $0;
$progname =~ s!^.+/([^/]+)$!$1!;
debug(1,<<"USAGE");
$progname: Incorrect invocation!
What you always have to specify:
- How to get to the information: a DSN (--dsn), the table name (--tbl),
and probably the database user (--dbuser) and password (--dbpass)
- An action to perform: --new_user, --mod_user, --remove_user
- The attributes needed for your query (--login, --name, --level, --password)
- Optionally, to get a listing of the users in the database, use --dump_users
User creation example:
$progname --dsn 'dbi:Pg:dbname=database;host=some.host.org'
--table user_simple --dbuser useradmin --dbpass s3kr3t --new_user
--login joe --name 'Joe Schmoe' --passwd mys3kr17 --level 5
User remotion:
$progname --dsn 'dbi:Pg:dbname=database;host=some.host.org'
--table user_simple--dbuser useradmin --dbpass s3kr3t --remove_user
--login john
User modification:
$progname --dsn 'dbi:Pg:dbname=database;host=some.host.org'
--table user_simple --dbuser useradmin --dbpass s3kr3t --new_user
--login joe --name 'Joe A. Schmoe' --passwd dont_forget_it --level 2
Please check the full documentation for further details:
perldoc $0
USAGE
exit 1;
}
sub dbconn_err {
debug(1,<<"DBERR");
Could not open DB connection - Please check that the provided data source
(dsn), user (dbuser) and password (dbpass) are correct.
DBERR
exit 2;
}
sub useradmin_err {
debug(1,<<"USERADMIN");
Could not create User::Simple::Admin - This might have happened because you
requested to create a table with the same name an existing one, or because you
asked to use a table which does not yet exist.
USERADMIN
exit 3;
}
sub newuser_err {
debug(1,<<"NEWUSER");
Could not create the requested user - This can be because the requested login
is already registered.
NEWUSER
exit 4;
}
sub no_user_err {
debug(1,<<"NOUSER");
Could not find the requested user in the database - The specified login might
be wrong, or the user might have been removed.
NOUSER
exit 5;
}
sub remove_err {
debug(1,<<"REMOVE");
Could not remove the requested user from the database - It might be being
referred to from another table if you have such a setup.
REMOVE
exit 6;
}
sub mod_err {
debug(1,<<"MODIF");
Could not modify the requested user in the database
MODIF
exit 7;
}
sub debug {
my $level = shift;
return unless $conf{verbose} >= $level;
warn @_,"\n";
}
|