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 | |
25 | foreach my $var (qw/create_requires create_allows update_requires update_allows/) |
26 | { |
27 | has $var => |
28 | ( |
29 | is => 'ro', |
30 | isa => ArrayRef[Str|HashRef], |
31 | traits => ['Array'], |
32 | default => sub { [] }, |
33 | trigger => sub |
406086f3 |
34 | { |
d2739840 |
35 | my ($self, $new) = @_; |
36 | $self->check_column_relation($_, 1) for @$new; |
37 | }, |
38 | handles => |
39 | { |
40 | "get_${var}_column" => 'get', |
41 | "set_${var}_column" => 'set', |
42 | "delete_${var}_column" => 'delete', |
43 | "insert_${var}_column" => 'insert', |
44 | "count_${var}_column" => 'count', |
45 | "all_${var}_columns" => 'elements', |
46 | } |
47 | ); |
48 | |
d217cb80 |
49 | before "set_${var}_column" => sub { $_[0]->check_column_relation($_[2], 1) }; |
50 | before "insert_${var}_column" => 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' => ( |
65 | is => 'ro', |
66 | writer => '_set_prefetch_allows', |
67 | isa => ArrayRef[ArrayRef|Str|HashRef], |
68 | default => sub { [ ] }, |
69 | predicate => 'has_prefetch_allows', |
70 | traits => ['Array'], |
71 | handles => |
72 | { |
73 | all_prefetch_allows => 'elements', |
74 | }, |
75 | ); |
76 | |
77 | has 'prefetch_validator' => ( |
78 | is => 'ro', |
79 | isa => 'Catalyst::Controller::DBIC::API::Validator', |
80 | lazy_build => 1, |
81 | ); |
82 | |
83 | sub _build_prefetch_validator { |
84 | my $self = shift; |
85 | |
86 | sub _check_rel { |
87 | my ($self, $rel, $static, $validator) = @_; |
88 | if(ArrayRef->check($rel)) |
89 | { |
90 | foreach my $rel_sub (@$rel) |
91 | { |
92 | _check_rel($self, $rel_sub, $static, $validator); |
93 | } |
94 | } |
95 | elsif(HashRef->check($rel)) |
96 | { |
97 | while(my($k,$v) = each %$rel) |
98 | { |
99 | $self->check_has_relation($k, $v, undef, $static); |
100 | } |
101 | $validator->load($rel); |
102 | } |
103 | else |
104 | { |
105 | $self->check_has_relation($rel, undef, undef, $static); |
106 | $validator->load($rel); |
107 | } |
108 | } |
109 | |
110 | my $validator = Catalyst::Controller::DBIC::API::Validator->new; |
111 | |
112 | foreach my $rel ($self->all_prefetch_allows) { |
113 | _check_rel($self, $rel, 1, $validator); |
114 | } |
115 | |
116 | return $validator; |
117 | } |
118 | |
d2739840 |
119 | =attribute_public count_arg is: ro, isa: Str, default: 'list_count' |
120 | |
121 | count_arg controls how to reference 'count' in the the request_data |
122 | |
123 | =cut |
124 | |
125 | has 'count_arg' => ( is => 'ro', isa => Str, default => 'list_count' ); |
126 | |
127 | =attribute_public page_arg is: ro, isa: Str, default: 'list_page' |
128 | |
129 | page_arg controls how to reference 'page' in the the request_data |
130 | |
131 | =cut |
132 | |
133 | has 'page_arg' => ( is => 'ro', isa => Str, default => 'list_page' ); |
134 | |
33003023 |
135 | =attribute_public offset_arg is: ro, isa: Str, default: 'offset' |
136 | |
137 | offset_arg controls how to reference 'offset' in the the request_data |
138 | |
139 | =cut |
140 | |
141 | has 'offset_arg' => ( is => 'ro', isa => Str, default => 'list_offset' ); |
142 | |
d2739840 |
143 | =attribute_public select_arg is: ro, isa: Str, default: 'list_returns' |
144 | |
145 | select_arg controls how to reference 'select' in the the request_data |
146 | |
147 | =cut |
148 | |
149 | has 'select_arg' => ( is => 'ro', isa => Str, default => 'list_returns' ); |
150 | |
151 | =attribute_public as_arg is: ro, isa: Str, default: 'as' |
152 | |
153 | as_arg controls how to reference 'as' in the the request_data |
154 | |
155 | =cut |
156 | |
157 | has 'as_arg' => ( is => 'ro', isa => Str, default => 'as' ); |
158 | |
159 | =attribute_public search_arg is: ro, isa: Str, default: 'search' |
160 | |
161 | search_arg controls how to reference 'search' in the the request_data |
162 | |
163 | =cut |
164 | |
165 | has 'search_arg' => ( is => 'ro', isa => Str, default => 'search' ); |
166 | |
167 | =attribute_public grouped_by_arg is: ro, isa: Str, default: 'list_grouped_by' |
168 | |
169 | grouped_by_arg controls how to reference 'grouped_by' in the the request_data |
170 | |
171 | =cut |
172 | |
173 | has 'grouped_by_arg' => ( is => 'ro', isa => Str, default => 'list_grouped_by' ); |
174 | |
175 | =attribute_public ordered_by_arg is: ro, isa: Str, default: 'list_ordered_by' |
176 | |
177 | ordered_by_arg controls how to reference 'ordered_by' in the the request_data |
178 | |
179 | =cut |
180 | |
181 | has 'ordered_by_arg' => ( is => 'ro', isa => Str, default => 'list_ordered_by' ); |
182 | |
183 | =attribute_public prefetch_arg is: ro, isa: Str, default: 'list_prefetch' |
184 | |
185 | prefetch_arg controls how to reference 'prefetch' in the the request_data |
186 | |
187 | =cut |
188 | |
189 | has 'prefetch_arg' => ( is => 'ro', isa => Str, default => 'list_prefetch' ); |
190 | |
810de6af |
191 | =attribute_public stash_key is: ro, isa: Str, default: 'response' |
192 | |
193 | stash_key controls where in stash request_data should be stored |
194 | |
195 | =cut |
196 | |
197 | has 'stash_key' => ( is => 'ro', isa => Str, default => 'response'); |
198 | |
73517f50 |
199 | =attribute_public data_root is: ro, isa: Str, default: 'list' |
d2739840 |
200 | |
201 | data_root controls how to reference where the data is in the the request_data |
202 | |
203 | =cut |
204 | |
205 | has 'data_root' => ( is => 'ro', isa => Str, default => 'list'); |
206 | |
609916e5 |
207 | =attribute_public item_root is: ro, isa: Str, default: 'data' |
208 | |
209 | item_root controls how to reference where the data for single object |
210 | requests is in the the request_data |
211 | |
212 | =cut |
213 | |
214 | has 'item_root' => ( is => 'ro', isa => Str, default => 'data'); |
215 | |
d2739840 |
216 | =attribute_public total_entries_arg is: ro, isa: Str, default: 'totalcount' |
217 | |
218 | total_entries_arg controls how to reference 'total_entries' in the the request_data |
219 | |
220 | =cut |
221 | |
222 | has 'total_entries_arg' => ( is => 'ro', isa => Str, default => 'totalcount' ); |
223 | |
224 | =attribute_public use_json_boolean is: ro, isa: Bool, default: 0 |
225 | |
0b0bf911 |
226 | use_json_boolean controls whether JSON boolean types are used in the success parameter of the response or if raw strings are used |
d2739840 |
227 | |
228 | =cut |
229 | |
230 | has 'use_json_boolean' => ( is => 'ro', isa => Bool, default => 0 ); |
231 | |
232 | =attribute_public return_object is: ro, isa: Bool, default: 0 |
233 | |
234 | return_object controls whether the results of create/update are serialized and returned in the response |
235 | |
236 | =cut |
237 | |
238 | has 'return_object' => ( is => 'ro', isa => Bool, default => 0 ); |
239 | |
240 | =head1 DESCRIPTION |
241 | |
242 | 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. |
243 | |
244 | =cut |
245 | |
246 | 1; |