ffb830089bdbe363834311aa64498d32bc7e26a4
[catagits/Catalyst-Plugin-Authentication.git] / lib / Catalyst / Plugin / Authentication / User / Hash.pm
1 #!/usr/bin/perl
2
3 package Catalyst::Plugin::Authentication::User::Hash;
4 use base qw/Catalyst::Plugin::Authentication::User/;
5
6 use strict;
7 use warnings;
8
9 sub new {
10     my $class = shift;
11
12     bless { ( @_ > 1 ) ? @_ : %{ $_[0] } }, $class;
13 }
14
15 sub AUTOLOAD {
16     my $self = shift;
17     ( my $key ) = ( our $AUTOLOAD =~ m/([^:]*)$/ );
18
19     $self->_accessor( $key, @_ );
20 }
21
22 sub id {
23     my $self = shift;
24     $self->_accessor( "id", @_ );
25 }
26
27 ## deprecated. Let the base class handle this.
28 #    sub store {
29 #        my $self = shift;
30 #        $self->_accessor( "store", @_ ) || ref $self;
31 #    }
32
33 sub _accessor {
34     my $self = shift;
35     my $key  = shift;
36
37     if (@_) {
38         my $arr = $self->{__hash_obj_key_is_array}{$key} = @_ > 1;
39         $self->{$key} = $arr ? [@_] : shift;
40     }
41
42     my $data = $self->{$key};
43     ( $self->{__hash_obj_key_is_array}{$key} || $key =~ /roles/ )
44       ? @{ $data || [] }
45       : $data;
46 }
47
48 ## password portion of this is no longer necessary, but here for backwards compatibility.
49 my %features = (
50     password => {
51         clear      => ["password"],
52         crypted    => ["crypted_password"],
53         hashed     => [qw/hashed_password hash_algorithm/],
54         self_check => undef,
55     },
56     roles   => ["roles"],
57     session => 1,
58 );
59
60 sub supports {
61     my ( $self, @spec ) = @_;
62
63     my $cursor = \%features;
64
65     return 1 if @spec == 1 and exists $self->{ $spec[0] };
66
67     # traverse the feature list,
68     for (@spec) {
69         return if ref($cursor) ne "HASH";
70         $cursor = $cursor->{$_};
71     }
72
73     if ( ref $cursor ) {
74         die "bad feature spec: @spec" unless ref $cursor eq "ARRAY";
75
76         # check that all the keys required for a feature are in here
77         foreach my $key (@$cursor) {
78             return undef unless exists $self->{$key};
79         }
80
81         return 1;
82     }
83     else {
84         return $cursor;
85     }
86 }
87
88 sub for_session {
89     my $self = shift;
90     return $self->store && $self->id || $self; # if we have a store and an ID we serialize by ref, otherwise we serialize the whole user
91 }
92
93 sub from_session {
94     my ( $self, $c, $user ) = @_;
95     $user;
96 }
97
98 __PACKAGE__;
99
100 __END__
101
102 =pod
103
104 =head1 NAME
105
106 Catalyst::Plugin::Authentication::User::Hash - An easy authentication user
107 object based on hashes.
108
109 =head1 SYNOPSIS
110
111         use Catalyst::Plugin::Authentication::User::Hash;
112         
113         Catalyst::Plugin::Authentication::User::Hash->new(
114                 password => "s3cr3t",
115         );
116
117 =head1 DESCRIPTION
118
119 This implementation of authentication user handles is supposed to go hand in
120 hand with L<Catalyst::Plugin::Authentication::Store::Minimal>.
121
122 =head1 METHODS
123
124 =over 4
125
126 =item new @pairs
127
128 Create a new object with the key-value-pairs listed in the arg list.
129
130 =item supports
131
132 Checks for existence of keys that correspond with features.
133
134 =item for_session
135
136 Just returns $self, expecting it to be serializable.
137
138 =item from_session
139
140 Just passes returns the unserialized object, hoping it's intact.
141
142 =item AUTOLOAD
143
144 Accessor for the key whose name is the method.
145
146 =item id
147
148 =item store
149
150 Accessors that override superclass's dying virtual methods.
151
152 =back
153
154 =head1 SEE ALSO
155
156 L<Hash::AsObject>
157
158 =cut
159
160