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 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 # -------------------------------------------------------------
22 # -------------------------------------------------------------
24 __PACKAGE__->register_method(
25 method => "init_authenticate",
26 api_name => "open-ils.auth.authenticate.init",
27 argc => 1, #(username)
29 Generates a random seed and returns it. The client
30 must then perform md5_hex( \$seed . \$password ) and use that
31 as the passwordhash to open-ils.auth.authenticate.complete
35 __PACKAGE__->register_method(
36 method => "complete_authenticate",
37 api_name => "open-ils.auth.authenticate.complete",
38 argc => 2, #( barcode, passwdhash )
40 Client provides the username and passwordhash (see
41 open-ils.auth.authenticate.init). If their password hash is
42 correct for the given username, a session id is returned,
43 if not, "0" is returned
47 __PACKAGE__->register_method(
48 method => "retrieve_session",
49 api_name => "open-ils.auth.session.retrieve",
50 argc => 1, #( sessionid )
52 Pass in a sessionid and this returns the username associated with it
56 __PACKAGE__->register_method(
57 method => "delete_session",
58 api_name => "open-ils.auth.session.delete",
59 argc => 1, #( sessionid )
61 Pass in a sessionid and this delete it from the cache
66 # -------------------------------------------------------------
68 # -------------------------------------------------------------
69 # -------------------------------------------------------------
72 # -------------------------------------------------------------
73 # connect to the memcache server
74 # -------------------------------------------------------------
76 $cache_handle = OpenSRF::Utils::Cache->new('global');
80 # -------------------------------------------------------------
81 # We build a random hash and put the hash along with the
82 # username into memcache (so that any backend may fulfill the
84 # -------------------------------------------------------------
85 sub init_authenticate {
86 my( $self, $client, $username ) = @_;
87 my $seed = md5_hex( time() . $$ . rand() . $username );
88 $cache_handle->put_cache( "_open-ils_seed_$username", $seed, 30 );
89 warn "init happened with seed $seed\n";
93 # -------------------------------------------------------------
94 # The temporary hash is removed from memcache.
95 # We retrieve the password from storage and verify
96 # their password hash against our re-hashed version of the
97 # password. If all goes well, we return the session id.
98 # Otherwise, we return "0"
99 # If type is set to 'opac', then this is an opac login,
100 # otherwise, it's a staff login
101 # -------------------------------------------------------------
102 sub complete_authenticate {
103 my( $self, $client, $username, $passwdhash, $type ) = @_;
105 my $name = "open-ils.storage.direct.actor.user.search.usrname";
107 warn "Completing Authentication\n";
109 warn "Retrieving user from storage..\n";
110 my $user_list = OpenILS::Application::AppUtils->simple_scalar_request(
111 "open-ils.storage", $name, $username );
113 unless(ref($user_list)) {
114 throw OpenSRF::EX::ERROR
115 ("No user info returned from storage for $username");
118 warn "We have the user from storage with usrname $username\n";
120 my $user = $user_list->[0];
123 if(!$user or !ref($user) ) {
124 throw OpenSRF::EX::ERROR ("No user for $username");
127 my $password = $user->passwd();
128 warn "user passwd is $password\n";
131 throw OpenSRF::EX::ERROR ("No password exists for $username", ERROR);
134 warn "we have a password\n";
136 my $current_seed = $cache_handle->get_cache("_open-ils_seed_$username");
137 $cache_handle->delete_cache( "_open-ils_seed_$username" );
139 warn "Removed tmp data from cache\n";
141 unless($current_seed) {
142 throw OpenSRF::EX::User
143 ("User must call open-ils.auth.init_authenticate first (or respond faster)");
146 my $hash = md5_hex($current_seed . $password);
148 if( $hash eq $passwdhash ) {
149 # password is correct... do they have permission to login here?
151 my $timeout = 28800; #staff login timeout - different for opac?
153 if($type eq "opac") {
154 # 1 is the top level org unit (we should probably load the tree and get id from it)
155 warn "Checking user perms for OPAC login\n";
156 if($apputils->check_user_perms($user->id(), 1, "OPAC_LOGIN")) {
157 return OpenILS::Perm->new("OPAC_LOGIN");
161 my $session_id = md5_hex(time() . $$ . rand());
162 $cache_handle->put_cache( $session_id, $user, $timeout );
167 warn "User password is incorrect...\n"; # send exception
172 sub retrieve_session {
173 my( $self, $client, $sessionid ) = @_;
174 my $user = $cache_handle->get_cache($sessionid);
176 warn "No User returned from retrieve_session $sessionid\n";
178 if($user) {$user->clear_password();}
185 my( $self, $client, $sessionid ) = @_;
186 return $cache_handle->delete_cache($sessionid);