]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Auth.pm
added a common entityize function to prevent the contining spread
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Auth.pm
1 use strict; use warnings;
2 package OpenILS::Application::Auth;
3 use OpenILS::Application;
4 use base qw/OpenILS::Application/;
5 use OpenSRF::Utils::Cache;
6 use Digest::MD5 qw(md5_hex);
7 use OpenSRF::Utils::Logger qw(:level);
8 use OpenILS::Utils::Fieldmapper;
9 use OpenSRF::EX qw(:try);
10 use OpenILS::Application::AppUtils;
11 use OpenILS::Perm;
12 use OpenILS::Application::AppUtils;
13
14 # memcache handle
15 my $cache_handle;
16 my $apputils = "OpenILS::Application::AppUtils";
17
18
19 # ----------------------------------------------------------------------------
20 #
21 # XXX This module is deprecated.  Use the oils_auth.so C module.
22 #
23 # ----------------------------------------------------------------------------
24
25
26
27
28
29
30
31
32
33
34
35 # -------------------------------------------------------------
36 # Methods
37 # -------------------------------------------------------------
38 # -------------------------------------------------------------
39
40 __PACKAGE__->register_method(
41         method  => "init_authenticate",
42         api_name        => "open-ils.auth.authenticate.init",
43         argc            => 1, #(username) 
44         note            =>      <<TEXT,
45 Generates a random seed and returns it.  The client
46 must then perform md5_hex( \$seed . \$password ) and use that
47 as the passwordhash to open-ils.auth.authenticate.complete
48 TEXT
49 );
50
51 __PACKAGE__->register_method(
52         method  => "complete_authenticate",
53         api_name        => "open-ils.auth.authenticate.complete",
54         argc            => 2, #( barcode, passwdhash )
55         note            => <<TEXT,
56 Client provides the username and passwordhash (see 
57 open-ils.auth.authenticate.init).  If their password hash is 
58 correct for the given username, a session id is returned, 
59 if not, "0" is returned
60 TEXT
61 );
62
63 __PACKAGE__->register_method(
64         method  => "retrieve_session",
65         api_name        => "open-ils.auth.session.retrieve",
66         argc            => 1, #( sessionid )
67         note            => <<TEXT,
68 Pass in a sessionid and this returns the username associated with it
69 TEXT
70 );
71
72 __PACKAGE__->register_method(
73         method  => "delete_session",
74         api_name        => "open-ils.auth.session.delete",
75         argc            => 1, #( sessionid )
76         note            => <<TEXT,
77 Pass in a sessionid and this delete it from the cache 
78 TEXT
79 );
80
81
82 # -------------------------------------------------------------
83 # Implementation
84 # -------------------------------------------------------------
85 # -------------------------------------------------------------
86
87
88 # -------------------------------------------------------------
89 # connect to the memcache server
90 # -------------------------------------------------------------
91 sub child_init {
92         $cache_handle = OpenSRF::Utils::Cache->new('global');
93 }
94
95
96 # -------------------------------------------------------------
97 # We build a random hash and put the hash along with the 
98 # username into memcache (so that any backend may fulfill the
99 # auth request).
100 # -------------------------------------------------------------
101 sub init_authenticate {
102         my( $self, $client, $username ) = @_;
103         my $seed = md5_hex( time() . $$ . rand() . $username );
104         $cache_handle->put_cache( "_open-ils_seed_$username", $seed, 30 );
105         warn "init happened with seed $seed\n";
106         return $seed;
107 }
108
109 # -------------------------------------------------------------
110 # The temporary hash is removed from memcache.  
111 # We retrieve the password from storage and verify
112 # their password hash against our re-hashed version of the 
113 # password. If all goes well, we return the session id. 
114 # Otherwise, we return "0"
115 # If type is set to 'opac', then this is an opac login,
116 # otherwise, it's a staff login
117 # -------------------------------------------------------------
118 sub complete_authenticate {
119         my( $self, $client, $username, $passwdhash, $type ) = @_;
120
121         my $name = "open-ils.cstore.direct.actor.user.search.atomic";
122
123         warn "Completing Authentication\n";
124
125         warn "Retrieving user from cstore..\n";
126         my $user_list = OpenILS::Application::AppUtils->simple_scalar_request(
127                         "open-ils.cstore", $name, { usrname => $username } );
128
129         unless(ref($user_list)) {
130                 return { ilsevent => 1000 };
131         }
132
133         warn "We have the user from cstore with usrname $username\n";
134
135         my $user = $user_list->[0];
136         
137
138         if(!$user or !ref($user) ) {
139                 return { ilsevent => 1000 };
140         }
141
142         my $password = $user->passwd();
143         warn "user passwd is $password\n";
144
145         if(!$password) {
146                 throw OpenSRF::EX::ERROR ("No password exists for $username", ERROR);
147         }
148
149         warn "we have a password\n";
150
151         my $current_seed = $cache_handle->get_cache("_open-ils_seed_$username");
152         $cache_handle->delete_cache( "_open-ils_seed_$username" );
153
154         warn "Removed tmp data from cache\n";
155
156         unless($current_seed) {
157                 throw OpenSRF::EX::User 
158                         ("User must call open-ils.auth.init_authenticate first (or respond faster)");
159         }
160
161         my $hash = md5_hex($current_seed . $password);
162
163         if( $hash eq $passwdhash ) {
164                 # password is correct... do they have permission to login here?
165
166                 my $timeout = 28800; #staff login timeout - different for opac?
167                 my $opactimeout = 604800; # 14 days
168
169                 if($type eq "opac") {
170                         # 1 is the top level org unit (we should probably load the tree and get id from it)
171                         warn "Checking user perms for OPAC login\n";
172                         if($apputils->check_user_perms($user->id(), 1, "OPAC_LOGIN")) {
173                                 return OpenILS::Perm->new("OPAC_LOGIN");
174                         }
175
176                 } else {
177                         # 1 is the top level org unit (we should probably load the tree and get id from it)
178                         warn "Checking user perms for Staff login\n";
179                         if($apputils->check_user_perms($user->id(), 1, "STAFF_LOGIN")) {
180                                 return OpenILS::Perm->new("STAFF_LOGIN");
181                         }
182                 }
183
184                 my $session_id = md5_hex(time() . $$ . rand()); 
185                 $cache_handle->put_cache( $session_id, $user, $timeout );
186                 #return $session_id;
187                 return { ilsevent => 0, authtoken => $session_id };
188
189         } else {
190
191                 warn "User password is incorrect...\n"; # send exception
192                 return { ilsevent => 1000 };
193         }
194 }
195
196 sub retrieve_session {
197         my( $self, $client, $sessionid ) = @_;
198         my $user =  $cache_handle->get_cache($sessionid);
199         if(!$user) {
200                 warn "No User returned from retrieve_session $sessionid\n";
201         }
202         if($user) {$user->clear_passwd();}
203         return $user;
204 }
205
206 sub delete_session {
207         my( $self, $client, $sessionid ) = @_;
208         return $cache_handle->delete_cache($sessionid);
209 }
210
211
212 1;