File Coverage

blib/lib/OIDC/Client/Role/ClaimsValidator.pm
Criterion Covered Total %
statement 72 72 100.0
branch 29 32 90.6
condition 3 5 60.0
subroutine 15 15 100.0
pod n/a
total 119 124 95.9


line stmt bran cond sub pod time code
1             package OIDC::Client::Role::ClaimsValidator;
2 3     3   275054 use utf8;
  3         451  
  3         32  
3 3     3   679 use Moose::Role;
  3         546691  
  3         42  
4 3     3   20652 use namespace::autoclean;
  3         7274  
  3         30  
5 3     3   410 use feature 'signatures';
  3         8  
  3         475  
6 3     3   28 no warnings 'experimental::signatures';
  3         7  
  3         171  
7 3     3   82 use Carp qw(croak);
  3         20  
  3         238  
8 3     3   24 use List::Util qw(any);
  3         10  
  3         280  
9 3     3   407 use OIDC::Client::Error::TokenValidation;
  3         26  
  3         3015  
10              
11             =encoding utf8
12              
13             =head1 NAME
14              
15             OIDC::Client::Role::ClaimsValidator - Claims Validator
16              
17             =head1 DESCRIPTION
18              
19             This Moose role covers private methods for validating token claims.
20              
21             =cut
22              
23              
24             requires qw(audience
25             provider_metadata
26             jwt_decoding_options);
27              
28              
29 27     27   51 sub _validate_issuer ($self, $issuer) {
  27         65  
  27         50  
  27         36  
30              
31 27 100       79 defined $issuer
32             or OIDC::Client::Error::TokenValidation->throw("OIDC: 'iss' claim is missing");
33              
34             my $expected_issuer = $self->provider_metadata->{issuer}
35 26 50       944 or croak("OIDC: issuer not found in provider metadata");
36              
37 26 100       112 $issuer eq $expected_issuer
38             or OIDC::Client::Error::TokenValidation->throw(
39             "OIDC: unexpected issuer, expected '$expected_issuer' but got '$issuer'"
40             );
41             }
42              
43              
44 24     24   37 sub _validate_audience ($self, $audience, $expected_audience) {
  24         34  
  24         35  
  24         50  
  24         33  
45              
46 24 100       87 defined $audience
47             or OIDC::Client::Error::TokenValidation->throw("OIDC: 'aud' claim is missing");
48              
49 23   66     653 $expected_audience ||= $self->audience;
50              
51 23 50       77 my @audiences = ref $audience eq 'ARRAY' ? @$audience : ($audience);
52              
53 23     23   87 any { $_ eq $expected_audience } @audiences
54             or OIDC::Client::Error::TokenValidation->throw(
55 23 100       124 "OIDC: unexpected audience, expected '$expected_audience' but got " . join(', ', map { "'$_'" } @audiences)
  3         21  
56             );
57             }
58              
59              
60 5     5   6 sub _validate_authorized_party ($self, $azp, $expected_authorized_party) {
  5         6  
  5         9  
  5         6  
  5         7  
61              
62 5 100       13 if (defined $expected_authorized_party) {
    100          
63 3 100       10 defined $azp
64             or OIDC::Client::Error::TokenValidation->throw("OIDC: 'azp' claim is missing");
65 2 100       27 $azp eq $expected_authorized_party
66             or OIDC::Client::Error::TokenValidation->throw(
67             "OIDC: unexpected authorized party, expected '$expected_authorized_party' but got '$azp'"
68             );
69             }
70             elsif (defined $azp) {
71 1         6 OIDC::Client::Error::TokenValidation->throw("OIDC: unexpected 'azp' claim");
72             }
73             }
74              
75              
76 3     3   6 sub _validate_subject ($self, $subject, $expected_subject) {
  3         3  
  3         5  
  3         4  
  3         6  
77              
78 3 100       9 defined $subject
79             or OIDC::Client::Error::TokenValidation->throw("OIDC: 'sub' claim is missing");
80              
81 2 100       9 $subject eq $expected_subject
82             or OIDC::Client::Error::TokenValidation->throw(
83             "OIDC: unexpected subject, expected '$expected_subject' but got '$subject'"
84             );
85             }
86              
87 3     3   6 sub _validate_nonce ($self, $nonce, $expected_nonce) {
  3         7  
  3         8  
  3         3  
  3         7  
88              
89 3 100       15 defined $nonce
90             or OIDC::Client::Error::TokenValidation->throw("OIDC: 'nonce' claim is missing");
91              
92 2 100       14 $nonce eq $expected_nonce
93             or OIDC::Client::Error::TokenValidation->throw(
94             "OIDC: unexpected nonce, expected '$expected_nonce' but got '$nonce'"
95             );
96             }
97              
98              
99 2     2   5 sub _validate_age ($self, $issued_at, $max_token_age) {
  2         4  
  2         4  
  2         5  
  2         3  
100              
101 2 50       8 defined $issued_at
102             or OIDC::Client::Error::TokenValidation->throw("OIDC: 'iat' claim is missing");
103              
104 2 100 50     100 $issued_at >= time - ($self->jwt_decoding_options->{leeway} // 0) - $max_token_age
105             or OIDC::Client::Error::TokenValidation->throw(
106             "OIDC: the token is too old"
107             );
108             }
109              
110              
111             1;