File Coverage

blib/lib/Authen/Pluggable.pm
Criterion Covered Total %
statement 47 54 87.0
branch 8 12 66.6
condition 4 12 33.3
subroutine 6 7 85.7
pod 3 3 100.0
total 68 88 77.2


line stmt bran cond sub pod time code
1             package Authen::Pluggable;
2             $Authen::Pluggable::VERSION = '0.03';
3 7     7   1410531 use Mojo::Base -base, -signatures;
  7         715423  
  7         46  
4 7     7   16793 use Mojo::Loader qw/load_class/;
  7         132388  
  7         3875  
5              
6             has '_providers' => sub { return {} };
7             has 'log';
8              
9 0     0   0 sub AUTOLOAD ($s) {
  0         0  
  0         0  
10 0         0 our $AUTOLOAD;
11 0         0 $AUTOLOAD =~ s/.*:://;
12 0         0 return $s->_providers->{$AUTOLOAD};
13             }
14              
15 5     5 1 20083 sub provider($s, $provider, $plugin=undef) {
  5         6  
  5         8  
  5         7  
  5         6  
16 5   66     19 $plugin //= $provider;
17 5         11 my %v = (provider => $plugin);
18             $s->_load_provider($provider, provider => $plugin)
19 5 100       15 unless exists($s->_providers->{$provider});
20 5         13 return $s->_providers->{$provider};
21             }
22              
23 2     2 1 23304 sub providers ( $s, @providers ) {
  2         5  
  2         3  
  2         4  
24 2         3 foreach my $provider (@providers) {
25 2 50       7 $provider = { $provider => undef } if (ref($provider) ne 'HASH');
26 2         11 while ( my ( $k, $v ) = each %$provider ) {
27 5         36 $s->_load_provider( $k, %$v );
28             }
29             }
30 2         21 return $s;
31             }
32              
33 9     9   17 sub _load_provider ( $s, $provider, %cfg ) {
  9         12  
  9         12  
  9         16  
  9         12  
34 9   33     26 my $class = delete($cfg{provider}) // $provider;
35 9         25 $class = __PACKAGE__ . "::$class";
36 9 50       40 unless ( my $e = load_class $class ) {
37 9   33     157 $s->_providers->{$provider} //= $class->new( parent => $s );
38 9 100       339 $s->_providers->{$provider}->cfg(%cfg) if (%cfg);
39             } else {
40 0 0 0     0 ( $s->log && $s->log->error($e) ) || croak $e;
41             }
42             }
43              
44 7     7 1 3279 sub authen ( $s, $user, $pass, $providers = [keys %{ $s->_providers }] ) {
  7         10  
  7         10  
  7         7  
  7         12  
  7         18  
  7         39  
45 7         11 foreach my $provider ( @$providers ) {
46 9         19 my $uinfo = $s->_providers->{$provider}->authen( $user, $pass );
47 9 100       22868 $uinfo && do {
48 5         12 $uinfo->{provider} = $provider;
49 5         21 return $uinfo;
50             }
51             }
52              
53 2         6 return undef;
54             }
55              
56             1;
57              
58             =pod
59              
60             =head1 NAME
61              
62             Authen::Pluggable - A Perl module to authenticate users via pluggable modules
63              
64             =for html

65            
66             github workflow tests
67            
68             Top language:
69             github last commit
70            

71              
72             =head1 VERSION
73              
74             version 0.03
75              
76             =head1 SYNOPSIS
77              
78             use Authen::Pluggable;
79              
80             my $auth = Authen::Pluggable->new();
81             $auth->provider('plugin1','plugin2');
82             $auth->plugin1->cfg({...});
83             $auth->plugin2->cfg({...});
84              
85             my $user_info = $auth->authen($username, $password) || die "Login failed";
86              
87             =head1 DESCRIPTION
88              
89             Authen::Pluggable is a Perl module to authenticate users via pluggable modules
90              
91             Every plugin class is in namespace C so you must omit it
92              
93             =encoding UTF-8
94              
95             =head1 METHODS
96              
97             =head2 new
98              
99             This method takes a hash of parameters. The following options are valid:
100              
101             =over
102              
103             =item log
104              
105             Any object that supports debug, info, error and warn.
106              
107             log => Log::Log4perl->get_logger('Authen::Simple::LDAP')
108              
109             =back
110              
111             =head2 provider($provider, $plugin [opt])
112              
113             If C<$plugin> is omitted C is loaded.
114             If C<$plugin> is set C is loaded with
115             C<$provider> as alias.
116              
117             It return the plugin object.
118              
119             =head2 providers(@providers)
120              
121             If C<@providers> items are scalar, they are considered as plugin name and they
122             are loaded. Else they can be hashref items. The hash key is considered as
123             plugin name if there isn't a provider key inside else it's considered as
124             alias name while provider key are considered as plugin name.
125              
126             $auth->providers('plugin1', 'plugin2')
127              
128             loads C and C
129              
130             $auth->providers(
131             { alias1 => {
132             provider => 'plugin1',
133             ... other configurations ...
134             },
135             alias2 => {
136             provider => 'plugin1',
137             ... other configurations ...
138             }
139             }
140             ),
141              
142             loads C two times, one with provider name C and
143             one with C. See L in test folder for an example with two
144             different password files
145              
146             It always return the object itself.
147              
148             =head2 authen($username, $password, [opt] $providers)
149              
150             Call all configured providers, or only $providers if configured, and return
151             the first with a valid authentication.
152              
153             The structure returned is usually something like this
154              
155             { provider => $provider, user => $user, cn => $cn, gid => $gid };
156              
157             where C<$provider> is the alias of the provider which return the valid
158             authentication and C<$cn> is the common name of the user.
159              
160             If no plugins return a valid authentication, this method returns undef.
161              
162             =head1 EXAMPLE FOR CONFIGURING PROVIDERS
163              
164             There are various methods to select the providers where autenticate and to configure it.
165             Here some example using chaining.
166              
167             This load and configure Passwd plugin
168              
169             $auth->provider('Passwd')->cfg(
170             'file' => ...
171             );
172              
173             This load and confgure AD plugin
174              
175             $auth->provider('AD')->cfg(%opt)
176              
177             Multiple configuration at one time via autoloaded methods
178              
179             $auth->providers( 'Passwd', 'AD' )
180             ->Passwd->cfg('file' => ...)
181             ->AD->cfg(%opt);
182              
183             Same but via providers hashref configuration
184              
185             $auth->providers({
186             'Passwd' => { 'file' => ... },
187             'AD' => \%opt,
188             });
189              
190             =head1 BUGS/CONTRIBUTING
191              
192             Please report any bugs through the web interface at L
193              
194             If you want to contribute changes or otherwise involve yourself in development, feel free to fork the Git repository from
195             L.
196              
197             =head1 SUPPORT
198              
199             You can find this documentation with the perldoc command too.
200              
201             perldoc Authen::Pluggable
202              
203             =head1 AUTHOR
204              
205             Emiliano Bruni
206              
207             =head1 COPYRIGHT AND LICENSE
208              
209             This software is copyright (c) 2022 by Emiliano Bruni.
210              
211             This is free software; you can redistribute it and/or modify it under
212             the same terms as the Perl 5 programming language system itself.
213              
214             =cut
215              
216             __END__