X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Controller-DBIC-API.git;a=blobdiff_plain;f=lib%2FCatalyst%2FController%2FDBIC%2FAPI%2FStaticArguments.pm;fp=lib%2FCatalyst%2FController%2FDBIC%2FAPI%2FStaticArguments.pm;h=ae53e0936d38699df98409b116f54d698183a6f1;hp=e2c2c902dca63c2d623ce64b10bdf966edc2a32e;hb=4e5983f2a904f894762e61c2dff962a37da5ef92;hpb=8c7199a13b832b6ce5e569320b3620dd38a67617 diff --git a/lib/Catalyst/Controller/DBIC/API/StaticArguments.pm b/lib/Catalyst/Controller/DBIC/API/StaticArguments.pm index e2c2c90..ae53e09 100644 --- a/lib/Catalyst/Controller/DBIC/API/StaticArguments.pm +++ b/lib/Catalyst/Controller/DBIC/API/StaticArguments.pm @@ -50,6 +50,72 @@ foreach my $var (qw/create_requires create_allows update_requires update_allows/ before "insert_${var}_column" => sub { $_[0]->check_column_relation($_[2], 1) }; #" } +=attribute_public prefetch_allows is: ro, isa: ArrayRef[ArrayRef|Str|HashRef] + +prefetch_allows limits what relations may be prefetched when executing searches with joins. This is necessary to avoid denial of service attacks in form of queries which would return a large number of data and unwanted disclosure of data. + +Like the synopsis in DBIC::API shows, you can declare a "template" of what is allowed (by using an '*'). Each element passed in, will be converted into a Data::DPath and added to the validator. + + prefetch_allows => [ 'cds', { cds => tracks }, { cds => producers } ] # to be explicit + prefetch_allows => [ 'cds', { cds => '*' } ] # wildcard means the same thing + +=cut + +has 'prefetch_allows' => ( + is => 'ro', + writer => '_set_prefetch_allows', + isa => ArrayRef[ArrayRef|Str|HashRef], + default => sub { [ ] }, + predicate => 'has_prefetch_allows', + traits => ['Array'], + handles => + { + all_prefetch_allows => 'elements', + }, +); + +has 'prefetch_validator' => ( + is => 'ro', + isa => 'Catalyst::Controller::DBIC::API::Validator', + lazy_build => 1, +); + +sub _build_prefetch_validator { + my $self = shift; + + sub _check_rel { + my ($self, $rel, $static, $validator) = @_; + if(ArrayRef->check($rel)) + { + foreach my $rel_sub (@$rel) + { + _check_rel($self, $rel_sub, $static, $validator); + } + } + elsif(HashRef->check($rel)) + { + while(my($k,$v) = each %$rel) + { + $self->check_has_relation($k, $v, undef, $static); + } + $validator->load($rel); + } + else + { + $self->check_has_relation($rel, undef, undef, $static); + $validator->load($rel); + } + } + + my $validator = Catalyst::Controller::DBIC::API::Validator->new; + + foreach my $rel ($self->all_prefetch_allows) { + _check_rel($self, $rel, 1, $validator); + } + + return $validator; +} + =attribute_public count_arg is: ro, isa: Str, default: 'list_count' count_arg controls how to reference 'count' in the the request_data