Name

Pg::Priv - PostgreSQL ACL parser and iterator

Synopsis

use DBI;
use Pg::Priv;

my $dbh = DBI->connect('dbi:Pg:dbname=template1', 'postgres', '');
my $sth = $dbh->prepare(
    q{SELECT relname, relacl FROM pg_class WHERE relkind = 'r'}
);

$sth->execute;
while (my $row = $sth->fetchrow_hashref) {
    print "Table $row->{relname}:\n";
    for my $priv ( Pg::Priv->parse_acl( $row->{relacl} ) ) {
        print '    ', $priv->by, ' granted to ', $priv->to, ': ',
            join( ', ', $priv->labels ), $/;
    }
}

Description

This module parses PostgreSQL ACL arrays and represents the underlying privileges as objects. Use accessors on the objects to see what privileges are granted by whom and to whom.

PostgreSQL ACLs are arrays of strings. Each string represents a single set of privileges granted by one role to another role. ACLs look something like this:

my $acl = [
   'miriam=arwdDxt/miriam',
   '=r/miriam',
   'admin=arw/miriam',
];

The format of the privileges are interpreted thus (borrowed from the PostgreSQL Documentation):

rolename=xxxx -- privileges granted to a role
        =xxxx -- privileges granted to PUBLIC

            r -- SELECT ("read")
            w -- UPDATE ("write")
            a -- INSERT ("append")
            d -- DELETE
            D -- TRUNCATE
            x -- REFERENCES
            t -- TRIGGER
            X -- EXECUTE
            U -- USAGE
            C -- CREATE
            c -- CONNECT
            T -- TEMPORARY
      arwdDxt -- ALL PRIVILEGES (for tables, varies for other objects)
            * -- grant option for preceding privilege

        /yyyy -- role that granted this privilege

Pg::Priv uses these rules (plus a few other gotchas here and there) to parse these privileges into objects. The above three privileges in the ACL array would thus be returned by parse_acl() as three Pg::Priv objects that you could then interrogate.

Interface

Class Methods

parse_acl

for my $priv ( Pg::Priv->parse_acl($acl) ) {
    print '    ', $priv->by, ' granted to ', $priv->to, ': ',
        join( ', ', $priv->labels ), $/;
}

Takes a PostgreSQL ACL array, parses it, and returns a list or array reference of Pg::Priv objects. Pass an optional second argument to specify that role names should be quoted as identifiers (like the PostgreSQL quote_ident() function does).

Constructor

new

my $priv = Pg::Priv->new(
    to    => $to,
    by    => $by,
    privs => $priv,
);

Constructs and returns a Pg::Priv object for the given grantor, grantee, and privileges. The privs parameter is a string representing the privileges, such as arwdxt. If you're fetching ACLs from PostgreSQL, you're more likely to want parse_acl(), which will figure this stuff out for you.

Instance Methods

to

Returns the name of the role to which the privileges were granted (the grantee).

by

Returns the name of the role that granted the privileges (the grantor).

privs

A string representing the privileges granted, such as arwdxt.

labels

A list or array reference of the labels for the granted privileges. These correspond to the uppercase labels shown in the description.

can

print "We can read!\n" if $priv->can('r');
print "We can read and write!\n" if $priv->can(qw(r w));

Pass in one or more privilege characters or labels and this method will return true if that all the privileges have been granted. If at least one of the specified privileges has not been granted, can returns false.

can_*

Convenience methods for verifying individual privileges:

can_select

Returns true if the SELECT privilege has been granted.

can_read

Returns true if the SELECT privilege has been granted.

can_update

Returns true if the UPDATE privilege has been granted.

can_write

Returns true if the UPDATE privilege has been granted.

can_insert

Returns true if the INSERT privilege has been granted.

can_append

Returns true if the INSERT privilege has been granted.

can_delete

Returns true if the DELETE privilege has been granted.

can_reference

Returns true if the REFERENCE privilege has been granted.

can_trigger

Returns true if the TRIGGER privilege has been granted.

can_execute

Returns true if the EXECUTE privilege has been granted.

can_usage

Returns true if the USAGE privilege has been granted.

can_create

Returns true if the CREATE privilege has been granted.

can_connect

Returns true if the CONNECT privilege has been granted.

can_temporary

Returns true if the TEMPORARY privilege has been granted.

can_temp

Returns true if the TEMPORARY privilege has been granted.

See Also

Acknowledgments

This module was originally developed under contract to Etsy, Inc.. Many thanks to them for agreeing to release it as open-source code!

Author

David E. Wheeler <david@justatheory.com>

Copyright and License

Copyright (c) 2009-2010 Etsy, Inc. and David. E. Wheeler. Some Rights Reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.