File Coverage

blib/lib/WebAPI/DBIC/Resource/Role/DBICAuth.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package WebAPI::DBIC::Resource::Role::DBICAuth;
2             $WebAPI::DBIC::Resource::Role::DBICAuth::VERSION = '0.003002';
3              
4 2     2   17561725 use Carp qw(confess);
  2         18  
  2         360  
5 2     2   1369 use Try::Tiny;
  2         6317  
  2         217  
6              
7 2     2   990 use WebAPI::DBIC::Util qw(create_header);
  0            
  0            
8              
9             use Moo::Role;
10              
11              
12             requires 'set';
13             requires 'http_auth_type';
14              
15             sub connect_schema_as { # XXX sub rather than method?
16             my ($self, $user, $pass) = @_;
17             $_[2] = '...'; # hide password from stack trace
18              
19             my $schema = $self->set->result_source->schema;
20             my $ci = $schema->storage->connect_info;
21             my ($ci_dsn, $ci_user, $ci_pass, $ci_attr) = @$ci;
22              
23             # ok if we're currently using the right auth
24             return 1 if defined $ci_user and $user eq $ci_user
25             and defined $ci_pass and $pass eq $ci_pass;
26              
27             # try to connect with the user supplied credentials
28             my $newschema = $schema->clone->connect($ci_dsn, $user, $pass, $ci_attr);
29             my $err;
30             try { $newschema->storage->dbh }
31             catch {
32             # XXX we need to differentiate between auth errors and other problems
33             warn "Error connecting to $ci_dsn: $_\n";
34             $err = $_;
35             };
36             return 0 if $err;
37              
38             # we connected ok, so update resultset to use new connection
39             # XXX Is this sane and safe?
40             $self->set->result_source->schema($newschema);
41              
42             return 1;
43             }
44              
45              
46             sub is_authorized {
47             my ($self, $auth_header) = @_;
48              
49             my $http_auth_type = $self->http_auth_type || '';
50             if ($http_auth_type =~ /^(none|disabled)$/) {
51             # This role was included in the resource, so auth was desired, yet auth
52             # has been specified. That seems worthy of a warning.
53             # 'none' gives a warning, but 'disabled' is silent.
54             (my $name = $self->request->path) =~ s:/\d+$::;
55             warn "HTTP authentication configured but not enabled for $name\n"
56             if $http_auth_type ne 'disabled'
57             and not our $warn_once->{"http_auth_type $name"}++;
58             return 1
59             }
60             elsif ($http_auth_type eq 'Basic') {
61              
62             # https://metacpan.org/pod/DBIx::Class::Storage::DBI#connect_info
63             my $ci = $self->set->result_source->schema->storage->connect_info;
64             # extract the dsn (doesn't handle $ci->[0] being a code ref)
65             my $dsn = (ref $ci->[0]) ? $ci->[0]->{dsn} : $ci->[0];
66             confess "Can't determine DSN to use as auth realm from @$ci"
67             if !$dsn or ref $dsn;
68              
69             my $auth_realm = "Insecure unless https! - $dsn"; # XXX get via a method
70             if ( $auth_header ) {
71             return 1 if $self->connect_schema_as($auth_header->username, $auth_header->password);
72             }
73             return create_header( 'WWWAuthenticate' => [ 'Basic' => ( realm => $auth_realm ) ] );
74             }
75              
76             die "Unsupported value for http_auth_type: $http_auth_type";
77             }
78              
79              
80             1;
81              
82             __END__
83              
84             =pod
85              
86             =encoding UTF-8
87              
88             =head1 NAME
89              
90             WebAPI::DBIC::Resource::Role::DBICAuth
91              
92             =head1 VERSION
93              
94             version 0.003002
95              
96             =head1 NAME
97              
98             WebAPI::DBIC::Resource::Role::DBICAuth - methods for authentication and authorization
99              
100             =head1 AUTHOR
101              
102             Tim Bunce <Tim.Bunce@pobox.com>
103              
104             =head1 COPYRIGHT AND LICENSE
105              
106             This software is copyright (c) 2015 by Tim Bunce.
107              
108             This is free software; you can redistribute it and/or modify it under
109             the same terms as the Perl 5 programming language system itself.
110              
111             =cut