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;
12 use OpenILS::Application::AppUtils;
16 my $apputils = "OpenILS::Application::AppUtils";
19 # ----------------------------------------------------------------------------
21 # XXX This module is deprecated. Use the oils_auth.so C module.
23 # ----------------------------------------------------------------------------
35 # -------------------------------------------------------------
37 # -------------------------------------------------------------
38 # -------------------------------------------------------------
40 __PACKAGE__->register_method(
41 method => "init_authenticate",
42 api_name => "open-ils.auth.authenticate.init",
43 argc => 1, #(username)
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
51 __PACKAGE__->register_method(
52 method => "complete_authenticate",
53 api_name => "open-ils.auth.authenticate.complete",
54 argc => 2, #( barcode, passwdhash )
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
63 __PACKAGE__->register_method(
64 method => "retrieve_session",
65 api_name => "open-ils.auth.session.retrieve",
66 argc => 1, #( sessionid )
68 Pass in a sessionid and this returns the username associated with it
72 __PACKAGE__->register_method(
73 method => "delete_session",
74 api_name => "open-ils.auth.session.delete",
75 argc => 1, #( sessionid )
77 Pass in a sessionid and this delete it from the cache
82 # -------------------------------------------------------------
84 # -------------------------------------------------------------
85 # -------------------------------------------------------------
88 # -------------------------------------------------------------
89 # connect to the memcache server
90 # -------------------------------------------------------------
92 $cache_handle = OpenSRF::Utils::Cache->new('global');
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
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";
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 ) = @_;
121 my $name = "open-ils.cstore.direct.actor.user.search.atomic";
123 warn "Completing Authentication\n";
125 warn "Retrieving user from cstore..\n";
126 my $user_list = OpenILS::Application::AppUtils->simple_scalar_request(
127 "open-ils.cstore", $name, { usrname => $username } );
129 unless(ref($user_list)) {
130 return { ilsevent => 1000 };
133 warn "We have the user from cstore with usrname $username\n";
135 my $user = $user_list->[0];
138 if(!$user or !ref($user) ) {
139 return { ilsevent => 1000 };
142 my $password = $user->passwd();
143 warn "user passwd is $password\n";
146 throw OpenSRF::EX::ERROR ("No password exists for $username", ERROR);
149 warn "we have a password\n";
151 my $current_seed = $cache_handle->get_cache("_open-ils_seed_$username");
152 $cache_handle->delete_cache( "_open-ils_seed_$username" );
154 warn "Removed tmp data from cache\n";
156 unless($current_seed) {
157 throw OpenSRF::EX::User
158 ("User must call open-ils.auth.init_authenticate first (or respond faster)");
161 my $hash = md5_hex($current_seed . $password);
163 if( $hash eq $passwdhash ) {
164 # password is correct... do they have permission to login here?
166 my $timeout = 28800; #staff login timeout - different for opac?
167 my $opactimeout = 604800; # 14 days
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");
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");
184 my $session_id = md5_hex(time() . $$ . rand());
185 $cache_handle->put_cache( $session_id, $user, $timeout );
187 return { ilsevent => 0, authtoken => $session_id };
191 warn "User password is incorrect...\n"; # send exception
192 return { ilsevent => 1000 };
196 sub retrieve_session {
197 my( $self, $client, $sessionid ) = @_;
198 my $user = $cache_handle->get_cache($sessionid);
200 warn "No User returned from retrieve_session $sessionid\n";
202 if($user) {$user->clear_passwd();}
207 my( $self, $client, $sessionid ) = @_;
208 return $cache_handle->delete_cache($sessionid);