Added the checkPrivileges method, borrowed from SQLForm.
Wrote tests based on SQLForm bugs to validate it, and it passes.
This commit is contained in:
parent
3d016a366b
commit
cff3ac1816
2 changed files with 149 additions and 1 deletions
|
|
@ -17,7 +17,9 @@ package WebGUI::DatabaseLink;
|
|||
|
||||
use strict;
|
||||
use Tie::CPHash;
|
||||
use WebGUI::SQL;
|
||||
use WebGUI::International;
|
||||
use WebGUI::Utility;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -46,6 +48,75 @@ These subroutines are available from this package:
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 checkPrivileges ( $requestedPrivileges, [$overrideGrants] )
|
||||
|
||||
Checks that the database has the requested set of privileges and returns true if it
|
||||
does.
|
||||
|
||||
=head3 requestedPrivileges
|
||||
|
||||
An array reference containing the list of privileges to check for this database.
|
||||
|
||||
=head3 overrideGrants
|
||||
|
||||
An array reference that allows for testing of arbitrary grants. This argument is
|
||||
solely for testing, as it bypasses querying the database for grants.
|
||||
|
||||
=cut
|
||||
|
||||
sub checkPrivileges {
|
||||
my $self = shift;
|
||||
my $requestedPrivileges = shift;
|
||||
my $overrideGrants = shift;
|
||||
|
||||
##Get the grants for the database, respecting the override if it has
|
||||
##been passed.
|
||||
my @grants;
|
||||
if (defined $overrideGrants) {
|
||||
@grants = @{ $overrideGrants };
|
||||
}
|
||||
else {
|
||||
@grants = $self->db->buildArray('show grants for current_user');
|
||||
}
|
||||
|
||||
##Parse through the grants, building both the list of grants and the
|
||||
##database which they belong to.
|
||||
my @privileges;
|
||||
foreach (@grants) {
|
||||
##Checks for grants on all databases '*' or grants on a specific database
|
||||
if (m/GRANT ([\w\s\d,]*?) ON ([^.]+)/) {
|
||||
my ($privileges, $database) = ($1, $2);
|
||||
$database =~ tr/`//d;
|
||||
$database =~ s/[%*]/.*/g;
|
||||
if ($self->databaseName() =~ /$database/) {
|
||||
push(@privileges, (split(/, /,$privileges)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Check if we found any privileges at all
|
||||
if (! scalar @privileges) {
|
||||
$self->session->errorHandler->warn(
|
||||
sprintf( "DatabaseLink: Could not find SQL privileges or no privileges on database '%s' for user '%s' with database link ID '%s' using DSN '%s'",
|
||||
$self->databaseName, $self->get->{username},
|
||||
$self->getId, $self->get->{DSN},
|
||||
)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Check if all required privs are present.
|
||||
return 1 if (isIn('ALL PRIVILEGES', @privileges));
|
||||
|
||||
foreach (@{ $requestedPrivileges }) {
|
||||
return 0 unless (isIn(uc($_), @privileges));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 copy ( )
|
||||
|
||||
Returns a new database link id, after copying the properties of this database link to a new entry.
|
||||
|
|
|
|||
|
|
@ -55,7 +55,75 @@ my $DSNs = [
|
|||
},
|
||||
];
|
||||
|
||||
plan tests => 2 + scalar @{ $DSNs };
|
||||
#Grants for parsing tests, particularly the database name
|
||||
my $grants = [
|
||||
{
|
||||
dsn => 'DBI:mysql:myDb:myHost:8008',
|
||||
privileges => [qw/ALTER CREATE INSERT DELETE/],
|
||||
grants => [
|
||||
'GRANT ALTER, CREATE, INSERT, DELETE ON *.* to user@localhost',
|
||||
],
|
||||
privileged => 1,
|
||||
comment => 'ACID on *.*, privileged',
|
||||
},
|
||||
{
|
||||
dsn => 'DBI:mysql:myDb:myHost:8008',
|
||||
privileges => [qw/ALTER CREATE INSERT DELETE/],
|
||||
grants => [
|
||||
'GRANT ALL PRIVILEGES ON *.* to user@localhost',
|
||||
],
|
||||
privileged => 1,
|
||||
comment => 'ALL PRIVILEGES on *.*, privileged',
|
||||
},
|
||||
{
|
||||
dsn => 'DBI:mysql:myDb:myHost:8008',
|
||||
privileges => [qw/ALTER CREATE INSERT DELETE/],
|
||||
grants => [
|
||||
'GRANT ALTER, CREATE, INSERT ON *.* to user@localhost',
|
||||
],
|
||||
privileged => 0,
|
||||
comment => 'Missing DELETE on *.*, unprivileged',
|
||||
},
|
||||
{
|
||||
dsn => 'DBI:mysql:myDb:myHost:8008',
|
||||
privileges => [qw/ALTER CREATE INSERT DELETE/],
|
||||
grants => [
|
||||
'GRANT ALL PRIVILEGES ON myDb.* to user@localhost',
|
||||
],
|
||||
privileged => 1,
|
||||
comment => 'ALL PRIVILEGES on explicit db name, privileged',
|
||||
},
|
||||
{
|
||||
dsn => 'DBI:mysql:myDb:myHost:8008',
|
||||
privileges => [qw/ALTER CREATE INSERT DELETE/],
|
||||
grants => [
|
||||
'GRANT ALL PRIVILEGES ON `myDb`.* to user@localhost',
|
||||
],
|
||||
privileged => 1,
|
||||
comment => 'ALL PRIVILEGES on quoted, explicit db name, privileged',
|
||||
},
|
||||
{
|
||||
dsn => 'DBI:mysql:myDb:myHost:8008',
|
||||
privileges => [qw/ALTER CREATE INSERT DELETE/],
|
||||
grants => [
|
||||
'GRANT ALL PRIVILEGES ON `my%`.* to user@localhost',
|
||||
],
|
||||
privileged => 1,
|
||||
comment => 'ALL PRIVILEGES on quoted, wildcard name, privileged',
|
||||
},
|
||||
{
|
||||
dsn => 'DBI:mysql:yourDb:myHost:8008',
|
||||
privileges => [qw/ALTER CREATE INSERT DELETE/],
|
||||
grants => [
|
||||
'GRANT ALL PRIVILEGES ON `my%`.* to user@localhost',
|
||||
],
|
||||
privileged => 0,
|
||||
comment => 'ALL PRIVILEGES on wrong db, unprivileged',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
plan tests => 2 + scalar @{ $DSNs } + scalar @{ $grants };
|
||||
|
||||
my $dbLink = WebGUI::DatabaseLink->new($session, 0);
|
||||
is($dbLink->get->{DSN}, $session->config->get('dsn'), 'DSN set correctly for default database link');
|
||||
|
|
@ -68,6 +136,15 @@ foreach my $dsn (@{ $DSNs }) {
|
|||
$dbl->delete;
|
||||
}
|
||||
|
||||
foreach my $grant (@{ $grants }) {
|
||||
my $dbl = WebGUI::DatabaseLink->create($session, { DSN => $grant->{dsn} });
|
||||
is(
|
||||
$dbl->checkPrivileges($grant->{privileges}, $grant->{grants}),
|
||||
$grant->{privileged},
|
||||
$grant->{comment}
|
||||
);
|
||||
$dbl->delete;
|
||||
}
|
||||
|
||||
END {
|
||||
foreach my $link ($dbLink, ) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue