]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Auth.pm
added some convenience methods, cleaned up some stuff,
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Auth.pm
1 use strict; use warnings;
2 package OpenILS::Application::Auth;
3 use OpenSRF::Application;
4 use base qw/OpenSRF::Application/;
5 use OpenSRF::Utils::Cache;
6 use Digest::MD5 qw(md5_hex);
7 use OpenSRF::Utils::Logger qw(:level);
8
9 # memcache handle
10 my $cache_handle;
11
12
13
14 # -------------------------------------------------------------
15 # Methods
16 # -------------------------------------------------------------
17 # -------------------------------------------------------------
18
19 __PACKAGE__->register_method(
20         method  => "init_authenticate",
21         api_name        => "open-ils.auth.authenticate.init",
22         argc            => 1, #(username) 
23         note            =>      <<TEXT,
24 Generates a random seed and returns it.  The client
25 must then perform md5_hex( \$seed . \$password ) and use that
26 as the passwordhash to open-ils.auth.authenticate.complete
27 TEXT
28 );
29
30 __PACKAGE__->register_method(
31         method  => "complete_authenticate",
32         api_name        => "open-ils.auth.authenticate.complete",
33         argc            => 2, #( barcode, passwdhash )
34         note            => <<TEXT,
35 Client provides the username and passwordhash (see 
36 open-ils.auth.authenticate.init).  If their password hash is 
37 correct for the given username, a session id is returned, 
38 if not, "0" is returned
39 TEXT
40 );
41
42 __PACKAGE__->register_method(
43         method  => "retrieve_session",
44         api_name        => "open-ils.auth.session.retrieve",
45         argc            => 1, #( sessionid )
46         note            => <<TEXT,
47 Pass in a sessionid and this returns the username associated with it
48 TEXT
49 );
50
51 __PACKAGE__->register_method(
52         method  => "delete_session",
53         api_name        => "open-ils.auth.session.delete",
54         argc            => 1, #( sessionid )
55         note            => <<TEXT,
56 Pass in a sessionid and this delete it from the cache 
57 TEXT
58 );
59
60
61 # -------------------------------------------------------------
62 # Implementation
63 # -------------------------------------------------------------
64 # -------------------------------------------------------------
65
66
67 # -------------------------------------------------------------
68 # connect to the memcache server
69 # -------------------------------------------------------------
70 sub initialize {
71
72         my $config_client = OpenSRF::Utils::SettingsClient->new();
73         my $memcache_servers = 
74                 $config_client->config_value( "apps","open-ils.auth", "app_settings","memcache" );
75
76         if( !$memcache_servers ) {
77                 throw OpenSRF::EX::Config ("No Memcache servers specified for open-ils.auth!");
78         }
79
80         if(!ref($memcache_servers)) {
81                 $memcache_servers = [$memcache_servers];
82         }
83         $cache_handle = OpenSRF::Utils::Cache->new( "open-ils.auth", $memcache_servers );
84 }
85
86
87
88 # -------------------------------------------------------------
89 # We build a random hash and put the hash along with the 
90 # username into memcache (so that any backend may fulfill the
91 # auth request).
92 # -------------------------------------------------------------
93 sub init_authenticate {
94         my( $self, $client, $username ) = @_;
95         my $seed = md5_hex( time() . $$ . rand() . $username );
96         $cache_handle->set( "_open-ils_seed_$username", $seed, 300 );
97         return $seed;
98 }
99
100 # -------------------------------------------------------------
101 # The temporary hash is removed from memcache.  
102 # We retrieve the password from storage and verify
103 # their password hash against our re-hashed version of the 
104 # password. If all goes well, we return the session id. 
105 # Otherwise, we return "0"
106 # -------------------------------------------------------------
107 sub complete_authenticate {
108         my( $self, $client, $username, $passwdhash ) = @_;
109
110         my $name = "open-ils.storage.actor.user.retrieve.username";
111         my $method = $self->method_lookup( $name );
112
113         my $password = undef;
114         if(!$method) {
115                 throw OpenSRF::EX::PANIC ("Could not lookup method $name");
116         }
117
118         my ($user) = $method->run($username);
119         if(!$user) {
120                 throw OpenSRF::EX::ERROR ("No user for $username");
121         }
122
123         $password = $user->{passwd};
124         if(!$password) {
125                 throw OpenSRF::EX::ERROR ("No password exists for $username", ERROR);
126         }
127
128         my $current_seed = $cache_handle->get("_open-ils_seed_$username");
129
130         unless($current_seed) {
131                 throw OpenILS::EX::User 
132                         ("User must call open-ils.auth.init_authenticate first (or respond faster)");
133         }
134
135         my $hash = md5_hex($current_seed . $password);
136         $cache_handle->delete( "_open-ils_seed_$username" );
137
138         if( $hash eq $passwdhash ) {
139
140                 my $session_id = md5_hex( time() . $$ . rand() ); 
141                 $cache_handle->set( $session_id, $username, 28800 );
142                 return $session_id;
143
144         } else {
145
146                 return 0;
147         }
148 }
149
150 sub retrieve_session {
151         my( $self, $client, $sessionid ) = @_;
152         return $cache_handle->get($sessionid);
153 }
154
155 sub delete_session {
156         my( $self, $client, $sessionid ) = @_;
157         return $cache_handle->delete($sessionid);
158 }
159
160
161 1;