1Catalyst::Plugin::AuthoUrsiezratCioonnt:r:iAbCuLt(e3d)PCeartlalDyosctu:m:ePnltuagtiino:n:Authorization::ACL(3)
2
3
4
6 Catalyst::Plugin::Authorization::ACL - ACL support for Catalyst
7 applications.
8
10 use Catalyst qw/
11 Authentication
12 Authorization::Roles
13 Authorization::ACL
14 /;
15
16 __PACKAGE__->setup;
17
18 __PACKAGE__->deny_access_unless(
19 "/foo/bar",
20 [qw/nice_role/],
21 );
22
23 __PACKAGE__->allow_access_if(
24 "/foo/bar/gorch",
25 sub { return $boolean },
26 );
27
29 This module provides Access Control List style path protection, with
30 arbitrary rules for Catalyst applications. It operates only on the
31 Catalyst private namespace, at least at the moment.
32
33 The two hierarchies of actions and controllers in Catalyst are:
34
35 Private Namespace
36 Every action has its own private path. This path reflects the Perl
37 namespaces the actions were born in, and the namespaces of their
38 controllers.
39
40 External Namespace
41 Some actions are also directly accessible from the outside, via a
42 URL.
43
44 The private and external paths will be the same, if you are using
45 Local actions. Alternatively you can use "Path", "Regex", or
46 "Global" to specify a different external path for your action.
47
48 The ACL module currently only knows to exploit the private namespace.
49 In the future extensions may be made to support external namespaces as
50 well.
51
52 Various types of rules are supported, see the list under "RULES".
53
54 When a path is visited, rules are tested one after the other, with the
55 most exact rule fitting the path first, and continuing up the path.
56 Testing continues until a rule explcitly allows or denies access.
57
59 allow_access_if
60 Arguments: $path, $rule
61
62 Check the rule condition and allow access to the actions under $path if
63 the rule returns true.
64
65 This is normally useful to allow acces only to a specific part of a
66 tree whose parent has a "deny_access_unless" clause attached to it.
67
68 If the rule test returns false access is not denied or allowed. Instead
69 the next rule in the chain will be checked - in this sense the
70 combinatory behavior of these rules is like logical OR.
71
72 allow_access_if_any
73 Arguments: $path, \@roles
74
75 Same as above for any role in the list.
76
77 deny_access_unless
78 Arguments: $path, $rule
79
80 Check the rule condition and disallow access if the rule returns false.
81
82 This is normally useful to restrict access to any portion of the
83 application unless a certain condition can be met.
84
85 If the rule test returns true access is not allowed or denied. Instead
86 the next rule in the chain will be checked - in this sense the
87 combinatory behavior of these rules is like logical AND.
88
89 deny_access_unless_any
90 Arguments: $path, \@roles
91
92 Same as above for any role in the list.
93
94 allow_access
95 deny_access
96 Arguments: $path
97
98 Unconditionally allow or deny access to a path.
99
100 acl_add_rule
101 Arguments: $path, $rule, [ $filter ]
102
103 Manually add a rule to all the actions under $path using the more
104 flexible (but more verbose) method:
105
106 __PACKAGE__->acl_add_rule(
107 "/foo",
108 sub { ... }, # see FLEXIBLE RULES below
109 sub {
110 my $action = shift;
111 # return a true value if you want to apply the rule to this action
112 # called for all the actions under "/foo"
113 }
114 };
115
116 In this case the rule must be a sub reference (or method name) to be
117 invoked on $c.
118
119 The default filter will skip all actions starting with an underscore,
120 namely "_DISPATCH", "_AUTO", etc (but not "auto", "begin", et al).
121
122 acl_access_denied
123 Arguments: $c, $class, $action, $err
124
125 acl_access_allowed
126 Arguments: $c, $class, $action
127
128 The default event handlers for access denied or allowed conditions. See
129 below on handling access violations.
130
131 acl_allow_root_internals
132 Adds rules that permit access to the root controller (YourApp.pm)
133 "auto", "begin" and "end" unconditionally.
134
136 execute
137 The hook for rule evaluation
138
139 setup_actions
141 When a rule is attached to an action the "distance" from the path it
142 was specified in is recorded. The closer the path is to the rule, the
143 earlier it will be checked.
144
145 Any rule can either explicitly deny or explicitly allow access to a
146 particular action. If a rule does not explicitly allow or permit
147 access, the next rule is checked, until the list of rules is finished.
148 If no rule has determined a policy, access to the path will be
149 permitted.
150
152 To apply a rule to an action or group of actions you must supply a
153 path.
154
155 This path is what you should see dumped at the beginning of the
156 Catalyst server's debug output.
157
158 For example, for the "foo" action defined at the root level of your
159 application, specify "/foo". Under the "Moose" controller (e.g.
160 "MyApp::C::Moose", the action "bar" will be "/moose/bar").
161
162 The "distance" a path has from an action that is contained in it is the
163 the difference in the number of slashes between the path of the action,
164 and the path to which the rule was applied.
165
167 Easy Rules
168 There are several kinds of rules you can create without using the
169 complex interface described in "FLEXIBLE RULES".
170
171 The easy rules are all predicate list oriented. "allow_access_if" will
172 explicitly allow access if the predicate is true, and
173 "deny_access_unless" will explicitly disallow if the predicate is
174 false.
175
176 Role Lists
177 __PACAKGE__->deny_access_unless_any( "/foo/bar", [qw/admin moose_trainer/] );
178
179 When the role is evaluated the
180 Catalyst::Plugin::Authorization::Roles will be used to check
181 whether the currently logged in user has the specified roles.
182
183 If "allow_access_if_any" is used, the presence of any of the roles
184 in the list will immediately permit access, and if
185 "deny_access_unless_any" is used, the lack of all of the roles will
186 immediately deny access.
187
188 Similarly, if "allow_access_if" is used, the presence of all the
189 roles will immediately permit access, and if "deny_access_unless"
190 is used, the lack of any of the roles will immediately deny access.
191
192 When specifying a role list without the
193 Catalyst::Plugin::Authorization::Roles plugin loaded the ACL engine
194 will throw an error.
195
196 Predicate Code Reference / Method Name
197 The code reference or method is invoked with the context and the
198 action objects. The boolean return value will determine the
199 behavior of the rule.
200
201 __PACKAGE__->allow_access_if( "/gorch", sub { ... } );
202 __PACKAGE__->deny_access_unless( "/moose", "method_name" );
203
204 When specifying a method name the rule engine ensures that it can
205 be invoked using "can" in UNIVERSAL.
206
207 Constant
208 You can use "undef", 0 and '' to use as a constant false predicate,
209 or 1 to use as a constant true predicate.
210
211 Flexible Rules
212 These rules are the most annoying to write but provide the most
213 flexibility.
214
215 All access control is performed using exceptions -
216 $Catalyst::Plugin::Authorization::ACL::Engine::DENIED, and
217 $Catalyst::Plugin::Authorization::ACL::Engine::ALLOWED (these can be
218 imported from the engine module).
219
220 If no rule decides to explicitly allow or deny access, access will be
221 permitted.
222
223 Here is a rule that will always break out of rule processing by either
224 explicitly allowing or denying access based on how much mojo the
225 current user has:
226
227 __PACKAGE__->acl_add_rule(
228 "/foo",
229 sub {
230 my ( $c, $action ) = @_;
231
232 if ( $c->user->mojo > 50 ) {
233 die $ALLOWED;
234 } else {
235 die $DENIED;
236 }
237 }
238 );
239
241 There are two plugin methods that can be called when a rule makes a
242 decision about an action:
243
244 acl_access_allowed
245 A no-op
246
247 acl_access_denied
248 Looks for a private action named "access_denied" from the denied
249 action's controller and outwards (much like "auto"), and if none is
250 found throws an access denied exception.
251
252 forcibly_allow_access
253 Within an "access_denied" action this will immediately cause the
254 blocked action to be executed anyway.
255
256 This means that you have several alternatives:
257
258 Provide an "access_denied" action
259 package MyApp::Controller::Foo;
260
261 sub access_denied : Private {
262 my ( $self, $c, $action ) = @_;
263
264 ...
265 $c->forcibly_allow_access
266 if $you->mean_it eq "really";
267 }
268
269 If you call "forcibly_allow_access" then the blocked action will be
270 immediately unblocked. Otherwise the execution of the action will
271 cease, and return to it's caller or end.
272
273 Cleanup in "end"
274 sub end : Private {
275 my ( $self, $c ) = @_;
276
277 if ( $c->error and $c->error->[-1] eq "access denied" ) {
278 $c->error(0); # clear the error
279
280 # access denied
281 } else {
282 # normal end
283 }
284 }
285
286 Override the plugin event handler methods
287 package MyApp;
288
289 sub acl_access_allowed {
290 my ( $c, $class, $action ) = @_;
291 ...
292 }
293
294 sub acl_access_denied {
295 my ( $c, $class, $action, $err ) = @_;
296 ...
297 }
298
299 $class is the controller class the $action object was going to be
300 executed in, and $err is the exception cought during rule evaluation,
301 if any (access is denied if a rule raises an exception).
302
304 Catalyst::Plugin::Authentication,
305 Catalyst::Plugin::Authorization::Roles,
306 <http://catalyst.perl.org/calendar/2005/24>
307
309 Yuval Kogman <nothingmuch@woobling.org>
310
312 castaway: Jess Robinson
313
314 caelum: Rafael Kitover <rkitover@cpan.org>
315
317 Copyright (c) 2005 - 2009 the Catalyst::Plugin::Authorization::ACL
318 "AUTHOR" and "CONTRIBUTORS" as listed above.
319
320 This library is free software; you can redistribute it and/or modify it
321 under the same terms as Perl itself.
322
323
324
325perl v5.36.0 2023-0C1a-t2a0lyst::Plugin::Authorization::ACL(3)