removed useless end-of-line comments
[catagits/Catalyst-Controller-DBIC-API.git] / lib / Catalyst / Controller / DBIC / API / StaticArguments.pm
index 71e8730..aff6689 100644 (file)
@@ -46,8 +46,74 @@ foreach my $var (qw/create_requires create_allows update_requires update_allows/
         }
     );
 
-    before "set_${var}_column" => sub { $_[0]->check_column_relation($_[2], 1) }; #"
-    before "insert_${var}_column" => sub { $_[0]->check_column_relation($_[2], 1) }; #"
+    before "set_${var}_column" => sub { $_[0]->check_column_relation($_[2], 1) };
+    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'
@@ -122,6 +188,14 @@ prefetch_arg controls how to reference 'prefetch' in the the request_data
 
 has 'prefetch_arg' => ( is => 'ro', isa => Str, default => 'list_prefetch' );
 
+=attribute_public stash_key is: ro, isa: Str, default: 'response'
+
+stash_key controls where in stash request_data should be stored
+
+=cut
+
+has 'stash_key' => ( is => 'ro', isa => Str, default => 'response');
+
 =attribute_public data_root is: ro, isa: Str, default: 'list'
 
 data_root controls how to reference where the data is in the the request_data
@@ -149,7 +223,7 @@ has 'total_entries_arg' => ( is => 'ro', isa => Str, default => 'totalcount' );
 
 =attribute_public use_json_boolean is: ro, isa: Bool, default: 0
 
-use_json_boolean controls whether JSON::Any boolean types are used in the success parameter of the response or if raw strings are used
+use_json_boolean controls whether JSON boolean types are used in the success parameter of the response or if raw strings are used
 
 =cut