Commit | Line | Data |
16585083 |
1 | #!/usr/bin/perl |
2 | |
3 | package Catalyst::Authentication::Store::Htpasswd; |
d2924b3f |
4 | # ABSTRACT: Authen::Htpasswd based user storage/authentication |
5 | |
16585083 |
6 | use base qw/Class::Accessor::Fast/; |
7 | use strict; |
8 | use warnings; |
9 | |
d2924b3f |
10 | use Authen::Htpasswd 0.13; |
16585083 |
11 | use Catalyst::Authentication::Store::Htpasswd::User; |
12 | use Scalar::Util qw/blessed/; |
13 | |
a44689b3 |
14 | our $VERSION = '1.006'; |
16585083 |
15 | |
1dc06313 |
16 | BEGIN { __PACKAGE__->mk_accessors(qw/file user_field user_class/) } |
16585083 |
17 | |
18 | sub new { |
19 | my ($class, $config, $app, $realm) = @_; |
20 | |
21 | my $file = delete $config->{file}; |
1dc06313 |
22 | unless (ref $file) { |
23 | my $filename = ($file =~ m|^/|) ? $file : $app->path_to($file)->stringify; |
16585083 |
24 | die("Cannot find htpasswd file: $filename\n") unless (-r $filename); |
25 | $file = Authen::Htpasswd->new($filename); |
26 | } |
27 | $config->{file} = $file; |
1dc06313 |
28 | $config->{user_class} ||= __PACKAGE__ . '::User'; |
29 | $config->{user_field} ||= 'username'; |
16585083 |
30 | |
31 | bless { %$config }, $class; |
32 | } |
33 | |
34 | sub find_user { |
35 | my ($self, $authinfo, $c) = @_; |
1dc06313 |
36 | my $htpasswd_user = $self->file->lookup_user($authinfo->{$self->user_field}); |
37 | $self->user_class->new( $self, $htpasswd_user ); |
16585083 |
38 | } |
39 | |
40 | sub user_supports { |
41 | my $self = shift; |
42 | |
1dc06313 |
43 | # this can work as a class method, but in that case you can't have |
44 | # a custom user class |
45 | ref($self) ? $self->user_class->supports(@_) |
46 | : Catalyst::Authentication::Store::Htpasswd::User->supports(@_); |
16585083 |
47 | } |
48 | |
49 | sub from_session { |
50 | my ( $self, $c, $id ) = @_; |
51 | $self->find_user( { username => $id } ); |
52 | } |
53 | |
54 | 1; |
55 | |
56 | __END__ |
57 | |
58 | =pod |
59 | |
16585083 |
60 | =head1 SYNOPSIS |
61 | |
62 | use Catalyst qw/ |
63 | Authentication |
64 | /; |
65 | |
66 | __PACKAGE__->config( |
67 | authentication => { |
68 | default_realm => 'test', |
69 | realms => { |
70 | test => { |
71 | credential => { |
72 | class => 'Password', |
73 | password_field => 'password', |
74 | password_type => 'self_check', |
75 | }, |
76 | store => { |
77 | class => 'Htpasswd', |
78 | file => 'htpasswd', |
79 | }, |
80 | }, |
81 | }, |
82 | }, |
83 | ); |
84 | |
85 | sub login : Global { |
86 | my ( $self, $c ) = @_; |
87 | |
88 | $c->authenticate({ username => $c->req->param("login"), password => $c->req->param("password") }); |
89 | } |
90 | |
91 | =head1 DESCRIPTION |
92 | |
8ba206fe |
93 | This plugin uses L<Authen::Htpasswd> to let your application use C<<.htpasswd>> |
16585083 |
94 | files for it's authentication storage. |
95 | |
96 | =head1 METHODS |
97 | |
98 | =head2 new |
99 | |
100 | Simple constructor, dies if the htpassword file can't be found |
101 | |
102 | =head2 find_user |
103 | |
104 | Looks up the user, and returns a Catalyst::Authentication::Store::Htpasswd::User object. |
105 | |
106 | =head2 user_supports |
107 | |
108 | Delegates to L<Catalyst::Authentication::Store::Htpasswd::User->user_supports|Catalyst::Authentication::Store::Htpasswd::User#user_supports> |
109 | |
110 | =head2 from_session |
111 | |
8ba206fe |
112 | Delegates the user lookup to C<< find_user >> |
16585083 |
113 | |
114 | =head1 CONFIGURATION |
115 | |
116 | =head2 file |
117 | |
1dc06313 |
118 | The path to the htpasswd file. If the path starts with a slash, then it is assumed to be a fully |
4149fcc0 |
119 | qualified path, otherwise the path is fed through C<< $c->path_to >> and so normalised to the |
1dc06313 |
120 | application root. |
121 | |
8bddfbc8 |
122 | Alternatively, it is possible to pass in an L<Authen::Htpasswd> object here, and this will be |
1dc06313 |
123 | used as the htpasswd file. |
124 | |
125 | =head2 user_class |
126 | |
8bddfbc8 |
127 | Change the user class which this store returns. Defaults to L<Catalyst::Authentication::Store::Htpasswd::User>. |
1dc06313 |
128 | This can be used to add additional functionality to the user class by sub-classing it, but will not normally be |
129 | needed. |
130 | |
131 | =head2 user_field |
132 | |
8ba206fe |
133 | Change the field that the username is found in in the information passed into the call to C<< $c->authenticate() >>. |
1dc06313 |
134 | |
135 | This defaults to I< username >, and generally you should be able to use the module as shown in the synopsis, however |
136 | if you need a different field name then this setting can change the default. |
137 | |
138 | Example: |
139 | |
140 | __PACKAGE__->config( authentication => { realms => { test => { |
141 | store => { |
142 | class => 'Htpasswd', |
143 | user_field => 'email_address', |
144 | }, |
145 | }}}); |
146 | # Later in your code |
147 | $c->authenticate({ email_address => $c->req->param("email"), password => $c->req->param("password") }); |
16585083 |
148 | |
16585083 |
149 | =head1 SEE ALSO |
150 | |
151 | L<Authen::Htpasswd>. |
152 | |
16585083 |
153 | =cut |