Commit | Line | Data |
d2739840 |
1 | package Catalyst::Controller::DBIC::API::StaticArguments; |
2 | |
3 | #ABSTRACT: Provides controller level configuration arguments |
4 | use Moose::Role; |
5 | use MooseX::Types::Moose(':all'); |
6 | use namespace::autoclean; |
7 | |
8 | requires 'check_column_relation'; |
9 | |
10 | =attribute_public create_requires create_allows update_requires update_allows |
11 | |
12 | These attributes control requirements and limits to columns when creating or updating objects. |
13 | |
14 | Each provides a number of handles: |
15 | |
16 | "get_${var}_column" => 'get' |
17 | "set_${var}_column" => 'set' |
18 | "delete_${var}_column" => 'delete' |
19 | "insert_${var}_column" => 'insert' |
20 | "count_${var}_column" => 'count' |
21 | "all_${var}_columns" => 'elements' |
22 | |
23 | =cut |
24 | |
8ea592cb |
25 | foreach my $var ( |
26 | qw( create_requires create_allows update_requires update_allows )) |
d2739840 |
27 | { |
8ea592cb |
28 | has $var => ( |
29 | is => 'ro', |
30 | isa => ArrayRef [ Str | HashRef ], |
31 | traits => ['Array'], |
d2739840 |
32 | default => sub { [] }, |
8ea592cb |
33 | trigger => sub { |
34 | my ( $self, $new ) = @_; |
35 | $self->check_column_relation( $_, 1 ) for @$new; |
d2739840 |
36 | }, |
8ea592cb |
37 | handles => { |
38 | "get_${var}_column" => 'get', |
39 | "set_${var}_column" => 'set', |
d2739840 |
40 | "delete_${var}_column" => 'delete', |
41 | "insert_${var}_column" => 'insert', |
8ea592cb |
42 | "count_${var}_column" => 'count', |
43 | "all_${var}_columns" => 'elements', |
d2739840 |
44 | } |
45 | ); |
46 | |
8ea592cb |
47 | before "set_${var}_column" => |
48 | sub { $_[0]->check_column_relation( $_[2], 1 ) }; |
49 | before "insert_${var}_column" => |
50 | sub { $_[0]->check_column_relation( $_[2], 1 ) }; |
d2739840 |
51 | } |
52 | |
4e5983f2 |
53 | =attribute_public prefetch_allows is: ro, isa: ArrayRef[ArrayRef|Str|HashRef] |
54 | |
55 | 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. |
56 | |
57 | 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. |
58 | |
59 | prefetch_allows => [ 'cds', { cds => tracks }, { cds => producers } ] # to be explicit |
60 | prefetch_allows => [ 'cds', { cds => '*' } ] # wildcard means the same thing |
61 | |
62 | =cut |
63 | |
64 | has 'prefetch_allows' => ( |
8ea592cb |
65 | is => 'ro', |
66 | writer => '_set_prefetch_allows', |
67 | isa => ArrayRef [ ArrayRef | Str | HashRef ], |
68 | default => sub { [] }, |
4e5983f2 |
69 | predicate => 'has_prefetch_allows', |
8ea592cb |
70 | traits => ['Array'], |
71 | handles => { all_prefetch_allows => 'elements', }, |
4e5983f2 |
72 | ); |
73 | |
74 | has 'prefetch_validator' => ( |
8ea592cb |
75 | is => 'ro', |
76 | isa => 'Catalyst::Controller::DBIC::API::Validator', |
4e5983f2 |
77 | lazy_build => 1, |
78 | ); |
79 | |
80 | sub _build_prefetch_validator { |
81 | my $self = shift; |
82 | |
83 | sub _check_rel { |
8ea592cb |
84 | my ( $self, $rel, $static, $validator ) = @_; |
85 | if ( ArrayRef->check($rel) ) { |
86 | foreach my $rel_sub (@$rel) { |
87 | _check_rel( $self, $rel_sub, $static, $validator ); |
4e5983f2 |
88 | } |
89 | } |
8ea592cb |
90 | elsif ( HashRef->check($rel) ) { |
91 | while ( my ( $k, $v ) = each %$rel ) { |
92 | $self->check_has_relation( $k, $v, undef, $static ); |
4e5983f2 |
93 | } |
94 | $validator->load($rel); |
95 | } |
8ea592cb |
96 | else { |
97 | $self->check_has_relation( $rel, undef, undef, $static ); |
4e5983f2 |
98 | $validator->load($rel); |
99 | } |
100 | } |
101 | |
102 | my $validator = Catalyst::Controller::DBIC::API::Validator->new; |
103 | |
8ea592cb |
104 | foreach my $rel ( $self->all_prefetch_allows ) { |
105 | _check_rel( $self, $rel, 1, $validator ); |
4e5983f2 |
106 | } |
107 | |
108 | return $validator; |
109 | } |
110 | |
d2739840 |
111 | =attribute_public count_arg is: ro, isa: Str, default: 'list_count' |
112 | |
113 | count_arg controls how to reference 'count' in the the request_data |
114 | |
115 | =cut |
116 | |
117 | has 'count_arg' => ( is => 'ro', isa => Str, default => 'list_count' ); |
118 | |
119 | =attribute_public page_arg is: ro, isa: Str, default: 'list_page' |
120 | |
121 | page_arg controls how to reference 'page' in the the request_data |
122 | |
123 | =cut |
124 | |
125 | has 'page_arg' => ( is => 'ro', isa => Str, default => 'list_page' ); |
126 | |
1255be67 |
127 | =attribute_public offset_arg is: ro, isa: Str, default: 'list_offset' |
33003023 |
128 | |
129 | offset_arg controls how to reference 'offset' in the the request_data |
130 | |
131 | =cut |
132 | |
133 | has 'offset_arg' => ( is => 'ro', isa => Str, default => 'list_offset' ); |
134 | |
d2739840 |
135 | =attribute_public select_arg is: ro, isa: Str, default: 'list_returns' |
136 | |
137 | select_arg controls how to reference 'select' in the the request_data |
138 | |
139 | =cut |
140 | |
141 | has 'select_arg' => ( is => 'ro', isa => Str, default => 'list_returns' ); |
142 | |
143 | =attribute_public as_arg is: ro, isa: Str, default: 'as' |
144 | |
145 | as_arg controls how to reference 'as' in the the request_data |
146 | |
147 | =cut |
148 | |
149 | has 'as_arg' => ( is => 'ro', isa => Str, default => 'as' ); |
150 | |
151 | =attribute_public search_arg is: ro, isa: Str, default: 'search' |
152 | |
153 | search_arg controls how to reference 'search' in the the request_data |
154 | |
155 | =cut |
156 | |
157 | has 'search_arg' => ( is => 'ro', isa => Str, default => 'search' ); |
158 | |
159 | =attribute_public grouped_by_arg is: ro, isa: Str, default: 'list_grouped_by' |
160 | |
161 | grouped_by_arg controls how to reference 'grouped_by' in the the request_data |
162 | |
163 | =cut |
164 | |
8ea592cb |
165 | has 'grouped_by_arg' => |
166 | ( is => 'ro', isa => Str, default => 'list_grouped_by' ); |
d2739840 |
167 | |
168 | =attribute_public ordered_by_arg is: ro, isa: Str, default: 'list_ordered_by' |
169 | |
170 | ordered_by_arg controls how to reference 'ordered_by' in the the request_data |
171 | |
172 | =cut |
173 | |
8ea592cb |
174 | has 'ordered_by_arg' => |
175 | ( is => 'ro', isa => Str, default => 'list_ordered_by' ); |
d2739840 |
176 | |
177 | =attribute_public prefetch_arg is: ro, isa: Str, default: 'list_prefetch' |
178 | |
179 | prefetch_arg controls how to reference 'prefetch' in the the request_data |
180 | |
181 | =cut |
182 | |
183 | has 'prefetch_arg' => ( is => 'ro', isa => Str, default => 'list_prefetch' ); |
184 | |
810de6af |
185 | =attribute_public stash_key is: ro, isa: Str, default: 'response' |
186 | |
187 | stash_key controls where in stash request_data should be stored |
188 | |
189 | =cut |
190 | |
8ea592cb |
191 | has 'stash_key' => ( is => 'ro', isa => Str, default => 'response' ); |
810de6af |
192 | |
73517f50 |
193 | =attribute_public data_root is: ro, isa: Str, default: 'list' |
d2739840 |
194 | |
195 | data_root controls how to reference where the data is in the the request_data |
196 | |
197 | =cut |
198 | |
8ea592cb |
199 | has 'data_root' => ( is => 'ro', isa => Str, default => 'list' ); |
d2739840 |
200 | |
609916e5 |
201 | =attribute_public item_root is: ro, isa: Str, default: 'data' |
202 | |
203 | item_root controls how to reference where the data for single object |
204 | requests is in the the request_data |
205 | |
206 | =cut |
207 | |
8ea592cb |
208 | has 'item_root' => ( is => 'ro', isa => Str, default => 'data' ); |
609916e5 |
209 | |
d2739840 |
210 | =attribute_public total_entries_arg is: ro, isa: Str, default: 'totalcount' |
211 | |
212 | total_entries_arg controls how to reference 'total_entries' in the the request_data |
213 | |
214 | =cut |
215 | |
8ea592cb |
216 | has 'total_entries_arg' => |
217 | ( is => 'ro', isa => Str, default => 'totalcount' ); |
d2739840 |
218 | |
219 | =attribute_public use_json_boolean is: ro, isa: Bool, default: 0 |
220 | |
0b0bf911 |
221 | use_json_boolean controls whether JSON boolean types are used in the success parameter of the response or if raw strings are used |
d2739840 |
222 | |
223 | =cut |
224 | |
225 | has 'use_json_boolean' => ( is => 'ro', isa => Bool, default => 0 ); |
226 | |
227 | =attribute_public return_object is: ro, isa: Bool, default: 0 |
228 | |
229 | return_object controls whether the results of create/update are serialized and returned in the response |
230 | |
231 | =cut |
232 | |
233 | has 'return_object' => ( is => 'ro', isa => Bool, default => 0 ); |
234 | |
235 | =head1 DESCRIPTION |
236 | |
237 | StaticArguments is a Role that is composed by the controller to provide configuration parameters such as how where in the request data to find specific elements, and if to use JSON boolean types. |
238 | |
239 | =cut |
240 | |
241 | 1; |