Thread [RFC] CGI::Application::Plugin::Authorization::Driver::DBIC
(0 answers)
Opened by
pktm
at 2009-05-27 23:41
User since 2003-08-07
2921
Artikel
BenutzerIn
Hallo!
Ich hätte mal gerne Kritik zu dem Modul, das ich hier zusammengeschustert habe. Es ist ein Aufsatz für DBIx::Class-basierte Webappliaktionen mit CGI::Application.
Es gibt dafür schon ein paar nette Module, aber ich verwende fürs Einloggen bereits CGI::Application::Plugin::Authentication::Driver::DBIC, und dem gebe ich ein Schema-Objekt mit. Das wollte ich dann einfach weiter verwenden. Sonst baue ich 2 Datenbankverbindungen auf.
Nun, hier der Code:
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
package CGI::Application::Plugin::Authorization::Driver::DBIC;
use warnings; use strict; use base 'CGI::Application::Plugin::Authorization::Driver';
=head1 NAME
CGI::Application::Plugin::Authorization::Driver::DBIC - DBIx::Class Authorization Driver
=head1 VERSION
Version 0.01
=cut
our $VERSION = '0.01';
=head1 SYNOPSIS
use base qw(CGI::Application); use CGI::Application::Plugin::Authentication; __PACKAGE__->authz->config( DRIVER => [ 'DBIC', SCHEMA => $self->schema(), CLASS => 'User', # = My::DBIC::User CLASS_CONSTRAINTS => { username => '__USERNAME__', },# = My::DBIC::Users->resultset('User')->search(\%CLASS_CONSTRAINTS)->single() RELATION => 'groups', # My::DBIC::User->has_many('groups') / _->many_to_many('groups', ...) RELATION_CONSTRAINTS => { group => '__GROUP__', },# = My::DBIC::Users->resultset('User')->search(\%CLASS_CONSTRAINTS)->single()->groups( \%RELATION_CONSTRAINTS ) ], );
# the same with CGI::Application::Plugin::Authorization::Driver::DBI __PACKAGE__->authz->config( DRIVER => [ 'DBI', DBH => $self->dbh(), TABLES => ['users', 'users2groups', 'groups'], JOIN_ON => 'users.user_id = users2groups.user_id AND users2groups.group_id = groups.group_id', CONSTRAINTS => { 'users.username' => '__USERNAME__', 'groups.group' => '__GROUP__', } ], );
# Using a named configuration to distinguish it from # the above configuration __PACKAGE__->authz('privileges')->config( DRIVER => [ 'DBIC', SCHEMA => $self->schema(), CLASS => 'User', CLASS_CONSTRAINTS => { username => '__USERNAME__', }, RELATION => 'privileges', RELATION_CONSTRAINTS => { package => '__PARAM_1__', privilege => '__PARAM_2__', }, ], );
# TODO: # a flat approach (not yet tested) # suitable if there is a 1:1 relation between user and groups. # (unfortunatley, this assumes a nonnormalized database layout) __PACKAGE__->authz->config( DRIVER => [ 'DBIC', SCHEMA => $self->schema(), CLASS => 'User', # = My::DBIC::User CLASS_CONSTRAINTS => { username => '__USERNAME__', group => '__GROUP__', }, ], );
=head1 DESCRIPTION
This Authorization driver uses the L<DBIx::Class> module to allow you to authorize against any I<DBIx::Class> class.
=head1 PARAMETERS
The I<DBIx::Class> Authentication driver accepts the following required parameters.
=over 4
=item SCHEMA (required)
Specifies the I<DBIx::Class::Schema> object to use for Authorization. This class must be loaded prior to use.
=item CLASS (required)
Specifies the I<DBIx::Class> class within the schema which contains Authorization information or accessors to lookup authorization information (see relation). Requires class constraints.
=item CLASS_CONSTRAINTS (required)
Specifies the constraints used to search for authenticating instances of the I<DBIx::Class> class.
=item RELATION (optional)
RELATION is the name of the method in the I<DBIx::Class> class (CLASS), that is accessed using RELATION_CONSTRAINTS.
Requires RELATION_CONSTRAINTS.
=back =head1 METHODS
=head2 authorize_user
This method accepts a username followed by a list of parameters and will return true if the configured query returns at least one row based on the given parameters.
=cut
sub authorize_user { my $self = shift; my $username = shift; my @params = @_; # constraint values are in here (except username)
# verify that all the options are OK my @_options = $self->options(); die "The DBIC driver requires a hash of options" if @_options % 2; my %options = @_options;
my $schema = $options{SCHEMA}; die "SCHEMA option must be set." unless($schema); die "SCHEMA must be a DBIx::Class::Schema." unless($schema->isa('DBIx::Class::Schema')); # or like CAP::Authz::Driver::DBH ? ## Get a schema handle either one that is given to us, or connect using ## the information given in the configuration #my $schema; #if ( $options{SCHEMA} ) { # $dbh = $options{SCHEMA}; #} elsif ( $self->authen->_cgiapp->can('schema') ) { # $dbh = $self->authen->_cgiapp->schema(); #} else { # die "No SCHEMA and no schema() method detected"; #}
my $class = $options{CLASS}; die "CLASS option must be set." unless($class);
my $relation = $options{RELATION}; die "RELATION option must be set." unless($relation); my $constraints_href = $options{CLASS_CONSTRAINTS}; die "CLASS_CONSTRAINTS must be a hashref" unless ref $options{CLASS_CONSTRAINTS} eq 'HASH';
# Process the constraints. # We need to check for values indicate they should be replaced by # a parameter (__PARAM_\d+__) my %class_constraints = (); my $used_username = 0; while ( my ( $column, $value ) = each %{ $options{CLASS_CONSTRAINTS} } ) { if ( $value =~ /^__PARAM_(\d+)__$/ ) { $value = $params[ $1 - 1 ]; } elsif ( $value =~ /^__USERNAME__$/ ) { $value = $username; $used_username = 1; } elsif ( $value =~ /^__GROUP__$/ ) { $value = $params[ 0 ]; } $class_constraints{$column} = $value; } if( $options{RELATION_CONSTRAINTS} ) { # There is also a relation to be checked. my %relation_constraints = (); my $used_username = 0; while ( my ( $column, $value ) = each %{ $options{RELATION_CONSTRAINTS} } ) { if ( $value =~ /^__PARAM_(\d+)__$/ ) { $value = $params[ $1 - 1 ]; } elsif ( $value =~ /^__USERNAME__$/ ) { $value = $username; $used_username = 1; } elsif ( $value =~ /^__GROUP__$/ ) { $value = $params[ 0 ]; } $relation_constraints{$column} = $value; } # Get the resultset. my $rs = $schema->resultset($class)->search(\%class_constraints)->single(); # Check reltaion constraints. my $count = $rs->$relation( \%relation_constraints )->count(); return $count ? 1 : 0; } # No relation to check. Only access the class. my $count = $schema->resultset($class)->search(\%class_constraints)->count();
# See if we matched at least one row. return $count ? 1 : 0; }
=head1 SEE ALSO
L<CGI::Application::Plugin::Authentication::Driver>, L<CGI::Application::Plugin::Authentication>, perl(1)
=head1 BUGS
Please report any bugs or feature requests to C<bug-cgi-application-plugin-Authentication-driver-dbic at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CGI-Application-Plugin-Authentication-Driver-DBIC>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc CGI::Application::Plugin::Authentication::Driver::DBIC
You can also look for information at:
=over 4
=item * AnnoCPAN: Annotated CPAN documentation
L<http://annocpan.org/dist/CGI-Application-Plugin-Authentication-Driver-DBIC>
=item * CPAN Ratings
L<http://cpanratings.perl.org/d/CGI-Application-Plugin-Authentication-Driver-DBIC>
=item * RT: CPAN's request tracker
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=CGI-Application-Plugin-Authentication-Driver-DBIC>
=item * Search CPAN
L<http://search.cpan.org/dist/CGI-Application-Plugin-Authentication-Driver-DBIC>
=back
=head1 THANKS
Cees Hek for I<CGI::Application::Plugin::Authorization>
Jaldhar H. Vyas and his module I<CGI::Application::Plugin::Authentication::Driver::DBIC> and Shawn Sorichetti I<CGI::Application::Plugin::Authentication::Driver::CDBI>.
=head1 AUTHOR
spam
=head1 COPYRIGHT & LICENSE
Copyright 2007, Consolidated Braincells Inc., all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
=cut
1; # End of CGI::Application::Plugin::Authentication::Driver::DBIC
Der ist im Moment angepasst auf mein Datenbanklayout. Da gibts Benutzer, Gruppen und Privilegien.
Ein Benutzer kann mehrere Benutzergruppen / Privilegien haben. Ich bilde das über solche Zwischen-Tabellen ab: Users -<1:n>- Users2Groups -<n:1>- Groups. Für Privilegien das Selbe.
Also, was meint ihr? Wo seht ihr Verbesserungspotential?
Grüße, pktm
Last edited: 2009-05-28 13:16:28 +0200 (CEST)
View full thread [RFC] CGI::Application::Plugin::Authorization::Driver::DBIC
|