File Coverage

File:lib/Yukki/Web/Router/Route/Match.pm
Coverage:90.6%

linestmtbrancondsubpodtimecode
1package Yukki::Web::Router::Route::Match;
2
3
1
1
5
2
use v5.24;
4
1
1
1
3
2
2
use utf8;
5
1
1
1
11
1
2
use Moo;
6
7extends 'Path::Router::Route::Match';
8
9
1
1
1
175
1
40
use List::Util qw( all any );
10
1
1
1
2
1
5
use Yukki::Error qw( http_throw );
11
12
1
1
1
187
2
3
use namespace::clean;
13
14# ABSTRACT: Matching with access controls
15
16 - 30
=head1 DESCRIPTION

This is a helper that include access control level checking.

=head1 EXTENDS

L<Path::Router::Route::Match>

=head1 METHODS

=head2 access_level

Evaluates the access control list against a particular path.

=cut
31
32sub access_level {
33
18
1
21
    my $self = shift;
34
35
18
36
    my $mapping = $self->mapping;
36
18
35
    my $acl     = $self->route->acl;
37
38
18
29
    for my $rule (@$acl) {
39
24
36
        my ($access_level, $match) = @$rule;
40
41        my $accepts = sub {
42
24
26
            my $key = shift;
43
44
24
62
            if (!ref $match->{$key}) {
45
0
0
                return $mapping->{$key} eq $match->{$key};
46            }
47            elsif (ref $match->{$key} eq 'CODE') {
48
3
5
                local $_ = $mapping->{$key};
49
3
14
                return $match->{$key}->($mapping->{$key});
50            }
51            elsif (ref $match->{$key} eq 'ARRAY') {
52
21
53
59
111
                return any { $mapping->{$key} eq $_ } $match->{$key}->@*;
53            }
54            else {
55
0
0
                die "unknown ACL authorization check type";
56            }
57
24
56
        };
58
59
24
24
59
37
        if (all { $accepts->($_) } keys %$match) {
60
18
39
            return $access_level;
61        }
62    }
63
64
0
    http_throw("no ACL found to match " . $self->path);
65}
66
671;