Fix broken links and malformed formatting in POD
[catagits/Catalyst-Authentication-Store-Htpasswd.git] / lib / Catalyst / Authentication / Store / Htpasswd.pm
1 #!/usr/bin/perl
2
3 package Catalyst::Authentication::Store::Htpasswd;
4 # ABSTRACT: Authen::Htpasswd based user storage/authentication
5
6 use base qw/Class::Accessor::Fast/;
7 use strict;
8 use warnings;
9
10 use Authen::Htpasswd 0.13;
11 use Catalyst::Authentication::Store::Htpasswd::User;
12 use Scalar::Util qw/blessed/;
13
14 our $VERSION = '1.007';
15
16 BEGIN { __PACKAGE__->mk_accessors(qw/file user_field user_class/) }
17
18 sub new {
19     my ($class, $config, $app, $realm) = @_;
20
21     my $file = delete $config->{file};
22     unless (ref $file) {
23         my $filename = ($file =~ m|^/|) ? $file : $app->path_to($file)->stringify;
24         die("Cannot find htpasswd file: $filename\n") unless (-r $filename);
25         $file = Authen::Htpasswd->new($filename);
26     }
27     $config->{file} = $file;
28     $config->{user_class} ||= __PACKAGE__ . '::User';
29     $config->{user_field} ||= 'username';
30
31     bless { %$config }, $class;
32 }
33
34 sub find_user {
35     my ($self, $authinfo, $c) = @_;
36     my $htpasswd_user = $self->file->lookup_user($authinfo->{$self->user_field});
37     $self->user_class->new( $self, $htpasswd_user );
38 }
39
40 sub user_supports {
41     my $self = shift;
42
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(@_);
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
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
93 This plugin uses L<Authen::Htpasswd> to let your application use C<< .htpasswd >>
94 files for its 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 L<Catalyst::Authentication::Store::Htpasswd::User> object.
105
106 =head2 user_supports
107
108 Delegates to L<< Catalyst::Authentication::User->supports|Catalyst::Authentication::User/supports >> or an
109 override in L<user_class|/user_class>.
110
111 =head2 from_session
112
113 Delegates the user lookup to L<find_user|/find_user>
114
115 =head1 CONFIGURATION
116
117 =head2 file
118
119 The path to the htpasswd file. If the path starts with a slash, then it is assumed to be a fully
120 qualified path, otherwise the path is fed through C<< $c->path_to >> and so normalised to the
121 application root.
122
123 Alternatively, it is possible to pass in an L<Authen::Htpasswd> object here, and this will be
124 used as the htpasswd file.
125
126 =head2 user_class
127
128 Change the user class which this store returns. Defaults to L<Catalyst::Authentication::Store::Htpasswd::User>.
129 This can be used to add additional functionality to the user class by sub-classing it, but will not normally be
130 needed.
131
132 =head2 user_field
133
134 Change the field that the username is found in in the information passed into the call to C<< $c->authenticate() >>.
135
136 This defaults to I< username >, and generally you should be able to use the module as shown in the synopsis, however
137 if you need a different field name then this setting can change the default.
138
139 Example:
140
141     __PACKAGE__->config( authentication => { realms => { test => {
142                     store => {
143                         class => 'Htpasswd',
144                         user_field => 'email_address',
145                     },
146     }}});
147     # Later in your code
148     $c->authenticate({ email_address => $c->req->param("email"), password => $c->req->param("password") });
149
150 =head1 SEE ALSO
151
152 L<Authen::Htpasswd>.
153
154 =cut