]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Auth.pm
Adding some initial permissions code
[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 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 # Methods
21 # -------------------------------------------------------------
22 # -------------------------------------------------------------
23
24 __PACKAGE__->register_method(
25         method  => "init_authenticate",
26         api_name        => "open-ils.auth.authenticate.init",
27         argc            => 1, #(username) 
28         note            =>      <<TEXT,
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
32 TEXT
33 );
34
35 __PACKAGE__->register_method(
36         method  => "complete_authenticate",
37         api_name        => "open-ils.auth.authenticate.complete",
38         argc            => 2, #( barcode, passwdhash )
39         note            => <<TEXT,
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
44 TEXT
45 );
46
47 __PACKAGE__->register_method(
48         method  => "retrieve_session",
49         api_name        => "open-ils.auth.session.retrieve",
50         argc            => 1, #( sessionid )
51         note            => <<TEXT,
52 Pass in a sessionid and this returns the username associated with it
53 TEXT
54 );
55
56 __PACKAGE__->register_method(
57         method  => "delete_session",
58         api_name        => "open-ils.auth.session.delete",
59         argc            => 1, #( sessionid )
60         note            => <<TEXT,
61 Pass in a sessionid and this delete it from the cache 
62 TEXT
63 );
64
65
66 # -------------------------------------------------------------
67 # Implementation
68 # -------------------------------------------------------------
69 # -------------------------------------------------------------
70
71
72 # -------------------------------------------------------------
73 # connect to the memcache server
74 # -------------------------------------------------------------
75 sub child_init {
76         $cache_handle = OpenSRF::Utils::Cache->new('global');
77 }
78
79
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
83 # auth request).
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";
90         return $seed;
91 }
92
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 ) = @_;
104
105         my $name = "open-ils.storage.direct.actor.user.search.usrname";
106
107         my $user_list = OpenILS::Application::AppUtils->simple_scalar_request(
108                         "open-ils.storage", $name, $username );
109
110         unless(ref($user_list)) {
111                 throw OpenSRF::EX::ERROR 
112                         ("No user info returned from storage for $username");
113         }
114
115         my $user = $user_list->[0];
116         
117
118         if(!$user or !ref($user) ) {
119                 throw OpenSRF::EX::ERROR ("No user for $username");
120         }
121
122         my $password = $user->passwd();
123
124         if(!$password) {
125                 throw OpenSRF::EX::ERROR ("No password exists for $username", ERROR);
126         }
127
128         my $current_seed = $cache_handle->get_cache("_open-ils_seed_$username");
129         $cache_handle->delete_cache( "_open-ils_seed_$username" );
130
131         unless($current_seed) {
132                 throw OpenSRF::EX::User 
133                         ("User must call open-ils.auth.init_authenticate first (or respond faster)");
134         }
135
136         my $hash = md5_hex($current_seed . $password);
137
138         if( $hash eq $passwdhash ) {
139                 # password is correct... do they have permission to login here?
140
141                 my $timeout = 28800; #staff login timeout - different for opac?
142
143                 if($type eq "opac") {
144                         # 1 is the top level org unit (we should probably load the tree and get id from it)
145                         warn "Checking user perms for OPAC login\n";
146                         if($apputils->check_user_perms($user->id(), 1, "OPAC_LOGIN")) {
147                                 return OpenILS::Perm->new("OPAC_LOGIN");
148                         }
149                 }
150
151                 my $session_id = md5_hex(time() . $$ . rand()); 
152                 $cache_handle->put_cache( $session_id, $user, $timeout );
153                 return $session_id;
154
155         } else {
156
157                 return 0;
158         }
159 }
160
161 sub retrieve_session {
162         my( $self, $client, $sessionid ) = @_;
163         my $user =  $cache_handle->get_cache($sessionid);
164         if(!$user) {
165                 warn "No User returned from retrieve_session $sessionid\n";
166         }
167         if($user) {$user->clear_password();}
168         use Data::Dumper;
169         warn Dumper $user;
170         return $user;
171 }
172
173 sub delete_session {
174         my( $self, $client, $sessionid ) = @_;
175         return $cache_handle->delete_cache($sessionid);
176 }
177
178
179 1;