File Coverage

blib/lib/Net/OAuth2Server/Response.pm
Criterion Covered Total %
statement 15 72 20.8
branch 0 34 0.0
condition 0 12 0.0
subroutine 5 22 22.7
pod 0 17 0.0
total 20 157 12.7


line stmt bran cond sub pod time code
1 1     1   5 use strict; use warnings;
  1     1   2  
  1         31  
  1         4  
  1         2  
  1         48  
2              
3             package Net::OAuth2Server::Response;
4             our $VERSION = '0.006';
5              
6 1     1   417 use Object::Tiny::Lvalue qw( parameters is_error redirect_uri use_fragment );
  1         400  
  1         4  
7 1     1   679 use URI::Escape ();
  1         1476  
  1         31  
8 1     1   7 use Carp ();
  1         2  
  1         975  
9              
10 0     0 0   sub supported_response_types { qw( code token ) }
11              
12 0     0 0   sub new { my $class = shift; bless { parameters => {}, @_ }, $class }
  0            
13              
14              
15             sub new_error {
16 0     0 0   my ( $class, $type, $desc, %param ) = ( shift, @_ );
17 0 0         $param{'error'} = $type or Carp::croak 'missing error type';
18 0 0         $param{'error_description'} = $desc if defined $desc;
19 0           $class->new( is_error => 1, parameters => \%param );
20             }
21              
22             sub for_authorization {
23 0     0 0   my ( $class, $req, $grant ) = ( shift, @_ );
24              
25 0 0         $req->set_error_unsupported_response_type
26             unless Net::OAuth2Server::Set
27             ->new( $class->supported_response_types )
28             ->contains_all( $req->response_type->list );
29              
30 0           my $self;
31 0 0         if ( $self = $req->error ) {}
    0          
32             elsif ( $grant ) {
33 0           $self = $class->new;
34 0 0         $grant->create_access_token( $self ) if $req->response_type->contains( 'token' );
35 0 0         $grant->create_auth_code( $self ) if $req->response_type->contains( 'code' );
36             }
37 0           else { $self = $class->new_error( 'access_denied' ) }
38              
39 0           $self->redirect_uri = $req->redirect_uri;
40 0           $self->use_fragment = $req->response_type->contains( 'token' ); # some kind of hybrid flow
41 0           $self->add( state => $req->param( 'state' ) );
42             }
43              
44             sub for_token {
45 0     0 0   my ( $class, $req, $grant ) = ( shift, @_ );
46 0   0       return $_ for $req->error || ();
47 0 0         return $class->new_error( 'invalid_grant' ) unless $grant;
48 0           my $self = $class->new;
49 0           $grant->create_access_token( $self );
50 0 0         $grant->create_refresh_token( $self ) if $grant->provides_refresh_token;
51 0           $self->add( scope => $grant->scope->as_string );
52             }
53              
54             #######################################################################
55              
56 0     0 0   sub params { my $p = shift->parameters; @$p{ @_ } }
  0            
57 0     0 0   sub param { my $p = shift->parameters; $$p{ $_[0] } }
  0            
58 0     0 0   sub has_param { my $p = shift->parameters; exists $$p{ $_[0] } }
  0            
59              
60             sub add {
61 0     0 0   my ( $self, $key, $value ) = ( shift, @_ );
62 0 0 0       $self->parameters->{ $key } = $value if defined $value and '' ne $value;
63 0           $self;
64             }
65              
66             sub add_token {
67 0     0 0   my ( $self, %arg ) = ( shift, @_ );
68 0 0         Carp::croak 'cannot add token to an error response' if $self->is_error;
69 0 0         Carp::croak "missing $_[0]" if not defined $_[1];
70 0           @{ $self->parameters }{ keys %arg } = values %arg;
  0            
71 0           $self;
72             }
73              
74 0     0 0   sub add_auth_code { shift->add_token( code => @_ ) }
75              
76             sub add_access_token {
77 0     0 0   my ( $self, $type, $token, $expires_in, %arg ) = ( shift, @_ );
78 0   0       $self->add_token( %arg, (
      0        
79             token_type => $type || ( Carp::croak 'missing token_type' ),
80             access_token => $token || ( Carp::croak 'missing access_token' ),
81             ( expires_in => $expires_in ) x defined $expires_in,
82             ) );
83             }
84              
85 0     0 0   sub add_bearer_token { shift->add_access_token( Bearer => @_ ) }
86              
87 0     0 0   sub add_refresh_token { shift->add_token( refresh_token => @_ ) }
88              
89             #######################################################################
90              
91 0 0   0 0   sub status { shift->is_error ? 400 : 200 }
92              
93             sub as_bearer_auth_header {
94 0     0 0   my $self = shift;
95 0 0         Carp::croak 'cannot create auth header from non-error response' if not $self->is_error;
96 0           my $p = $self->parameters;
97 0           'Bearer ' . join ', ', sort map qq{$_="$p->{ $_ }"}, keys %$p;
98             }
99              
100             my $e = \&URI::Escape::uri_escape;
101             sub as_uri {
102 0     0 0   my $self = shift;
103 0 0         my $uri = $self->redirect_uri or return;
104 0           my $p = $self->parameters;
105 0           my $idx = -1;
106 0           my $qps = join '&', map $e->( $_ ).'='.$e->( $p->{ $_ } ), keys %$p;
107 0 0         my $sep = $self->use_fragment ? '#' : $uri =~ /\?/ ? '&' : '?';
    0          
108 0           $uri . $sep . $qps;
109             }
110              
111             1;