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