patched up some typos
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / AppUtils.pm
1 package OpenILS::Application::AppUtils;
2 use strict; use warnings;
3 use base qw/OpenSRF::Application/;
4 use OpenSRF::Utils::Cache;
5 use OpenSRF::EX qw(:try);
6 use OpenILS::Perm;
7 use OpenSRF::Utils::Logger;
8 my $logger = "OpenSRF::Utils::Logger";
9
10
11 my $cache_client = "OpenSRF::Utils::Cache";
12
13 # ---------------------------------------------------------------------------
14 # Pile of utilty methods used accross applications.
15 # ---------------------------------------------------------------------------
16
17
18 # ---------------------------------------------------------------------------
19 # on sucess, returns the created session, on failure throws ERROR exception
20 # ---------------------------------------------------------------------------
21 sub start_db_session {
22
23         my $self = shift;
24         my $session = OpenSRF::AppSession->connect( "open-ils.storage" );
25         my $trans_req = $session->request( "open-ils.storage.transaction.begin" );
26
27         my $trans_resp = $trans_req->recv();
28         if(ref($trans_resp) and UNIVERSAL::isa($trans_resp,"Error")) { throw $trans_resp; }
29         if( ! $trans_resp->content() ) {
30                 throw OpenSRF::ERROR 
31                         ("Unable to Begin Transaction with database" );
32         }
33         $trans_req->finish();
34         return $session;
35 }
36
37
38 # returns undef if user has all of the perms provided
39 # returns the first failed perm on failure
40 sub check_user_perms {
41         my($self, $user_id, $org_id, @perm_types ) = @_;
42
43         $logger->debug("Checking perms with user : $user_id , org: $org_id, @perm_types");
44
45         throw OpenSRF::EX::ERROR ("Invalid call to check_user_perms()")
46                 unless( defined($user_id) and defined($org_id) and @perm_types); 
47
48         my $session = OpenSRF::AppSession->create("open-ils.storage");
49         for my $type (@perm_types) {
50                 my $req = $session->request(
51                         "open-ils.storage.permission.user_has_perm", 
52                         $user_id, $type, $org_id );
53                 my $resp = $req->gather(1);
54                 if(!$resp) { 
55                         $session->disconnect();
56                         return $type; 
57                 }
58         }
59
60         $session->disconnect();
61         return undef;
62 }
63
64 # checks the list of user perms.  The first one that fails returns a new
65 # OpenILS::Perm object of that type.  Returns undef if all perms are allowed
66 sub check_perms {
67         my( $self, $user_id, $org_id, @perm_types ) = @_;
68         my $t = $self->check_user_perms( $user_id, $org_id, @perm_types );
69         return OpenILS::Event->new('PERM_FAILURE', ilsperm => $t, ilspermloc => $org_id ) if $t;
70         return undef;
71 }
72
73
74
75 # ---------------------------------------------------------------------------
76 # commits and destroys the session
77 # ---------------------------------------------------------------------------
78 sub commit_db_session {
79         my( $self, $session ) = @_;
80
81         my $req = $session->request( "open-ils.storage.transaction.commit" );
82         my $resp = $req->recv();
83
84         if(!$resp) {
85                 throw OpenSRF::EX::ERROR ("Unable to commit db session");
86         }
87
88         if(UNIVERSAL::isa($resp,"Error")) { 
89                 throw $resp ($resp->stringify); 
90         }
91
92         if(!$resp->content) {
93                 throw OpenSRF::EX::ERROR ("Unable to commit db session");
94         }
95
96         $session->finish();
97         $session->disconnect();
98         $session->kill_me();
99 }
100
101 sub rollback_db_session {
102         my( $self, $session ) = @_;
103
104         my $req = $session->request("open-ils.storage.transaction.rollback");
105         my $resp = $req->recv();
106         if(UNIVERSAL::isa($resp,"Error")) { throw $resp;  }
107
108         $session->finish();
109         $session->disconnect();
110         $session->kill_me();
111 }
112
113 # ---------------------------------------------------------------------------
114 # Checks to see if a user is logged in.  Returns the user record on success,
115 # throws an exception on error.
116 # ---------------------------------------------------------------------------
117
118
119 sub check_user_session {
120
121         my( $self, $user_session ) = @_;
122
123         my $session = OpenSRF::AppSession->create( "open-ils.auth" );
124         my $request = $session->request("open-ils.auth.session.retrieve", $user_session );
125         my $response = $request->recv();
126
127         if(!$response) {
128                 throw OpenSRF::EX::User 
129                         ("Error communication with storage server");
130         }
131
132         if(ref($response) and $response->isa("OpenSRF::EX")) {
133                 throw $response ($response->stringify);
134         }
135
136
137         my $content = $response->content;
138         if( ref($content) eq 'HASH' ) {
139                 if(defined($content->{ilsevent}) and $content->{ilsevent} ne '0' ) {
140                         throw OpenSRF::EX::ERROR 
141                                 ("Session [$user_session] cannot be authenticated" );
142                 }
143         }
144
145         my $user = $content;
146         if(!$user) {
147                 throw OpenSRF::EX::ERROR 
148                         ("Session [$user_session] cannot be authenticated" );
149         }
150
151         $session->disconnect();
152         $session->kill_me();
153
154         return $user;
155 }
156
157 # generic simple request returning a scalar value
158 sub simplereq {
159         my($self, $service, $method, @params) = @_;
160         return $self->simple_scalar_request($service, $method, @params);
161 }
162
163
164 sub simple_scalar_request {
165         my($self, $service, $method, @params) = @_;
166
167         my $session = OpenSRF::AppSession->create( $service );
168         my $request = $session->request( $method, @params );
169         my $response = $request->recv(30);
170
171         $request->wait_complete;
172
173         if(!$request->complete) {
174                 throw OpenSRF::EX::ERROR ("Call to $service for method $method with params @params" . 
175                                 "\n did not complete successfully");
176         }
177
178         if(!$response) {
179                 warn "No response from $service for method $method with params @params";
180         }
181
182         if(UNIVERSAL::isa($response,"Error")) {
183                 throw $response ("Call to $service for method $method with params @params" . 
184                                 "\n failed with exception: " . $response->stringify );
185         }
186
187
188         $request->finish();
189         $session->finish();
190         $session->disconnect();
191
192         my $value;
193
194         if($response) { $value = $response->content; }
195         else { $value = undef; }
196
197         return $value;
198 }
199
200
201
202
203
204 my $tree                                                = undef;
205 my $orglist                                     = undef;
206 my $org_typelist                        = undef;
207 my $org_typelist_hash   = {};
208
209 sub get_org_tree {
210
211         my $self = shift;
212         if($tree) { return $tree; }
213
214         # see if it's in the cache
215         $tree = $cache_client->new()->get_cache('_orgtree');
216         if($tree) { return $tree; }
217
218         if(!$orglist) {
219                 warn "Retrieving Org Tree\n";
220                 $orglist = $self->simple_scalar_request( 
221                         "open-ils.storage", 
222                         "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
223         }
224
225         if( ! $org_typelist ) {
226                 warn "Retrieving org types\n";
227                 $org_typelist = $self->simple_scalar_request( 
228                         "open-ils.storage", 
229                         "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
230                 $self->build_org_type($org_typelist);
231         }
232
233         $tree = $self->build_org_tree($orglist,1);
234         $cache_client->new()->put_cache('_orgtree', $tree);
235         return $tree;
236
237 }
238
239 my $slimtree = undef;
240 sub get_slim_org_tree {
241
242         my $self = shift;
243         if($slimtree) { return $slimtree; }
244
245         # see if it's in the cache
246         $slimtree = $cache_client->new()->get_cache('slimorgtree');
247         if($slimtree) { return $slimtree; }
248
249         if(!$orglist) {
250                 warn "Retrieving Org Tree\n";
251                 $orglist = $self->simple_scalar_request( 
252                         "open-ils.storage", 
253                         "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
254         }
255
256         $slimtree = $self->build_org_tree($orglist);
257         $cache_client->new->put_cache('slimorgtree', $slimtree);
258         return $slimtree;
259
260 }
261
262
263 sub build_org_type { 
264         my($self, $org_typelist)  = @_;
265         for my $type (@$org_typelist) {
266                 $org_typelist_hash->{$type->id()} = $type;
267         }
268 }
269
270
271
272 sub build_org_tree {
273
274         my( $self, $orglist, $add_types ) = @_;
275
276         return $orglist unless ( 
277                         ref($orglist) and @$orglist > 1 );
278
279         my @list = sort { 
280                 $a->ou_type <=> $b->ou_type ||
281                 $a->name cmp $b->name } @$orglist;
282
283         for my $org (@list) {
284
285                 next unless ($org);
286
287                 if(!ref($org->ou_type()) and $add_types) {
288                         $org->ou_type( $org_typelist_hash->{$org->ou_type()});
289                 }
290
291                 next unless (defined($org->parent_ou));
292
293                 my ($parent) = grep { $_->id == $org->parent_ou } @list;
294                 next unless $parent;
295                 $parent->children([]) unless defined($parent->children); 
296                 push( @{$parent->children}, $org );
297         }
298
299         return $list[0];
300
301 }
302
303 sub fetch_user {
304         my $self = shift;
305         my $id = shift;
306         return $self->simple_scalar_request(
307                 'open-ils.storage',
308                 'open-ils.storage.direct.actor.user.retrieve', $id );
309 }
310
311 sub checkses {
312         my( $self, $session ) = @_;
313         my $user; my $evt; my $e; 
314
315         $logger->debug("Checking user session $session");
316
317         try {
318                 $user = $self->check_user_session($session);
319         } catch Error with { $e = 1; };
320
321         if( $e or !$user ) { $evt = OpenILS::Event->new('NO_SESSION'); }
322         return ( $user, $evt );
323 }
324
325
326 sub checkrequestor {
327         my( $self, $staffobj, $userid, @perms ) = @_;
328         my $user; my $evt;
329         $userid = $staffobj->id unless defined $userid;
330
331         $logger->debug("checkrequestor(): requestor => " . $staffobj->id . ", target => $userid");
332
333         if( $userid ne $staffobj->id ) {
334                 if( ! ($user = $self->fetch_user($userid)) ) {
335                         $evt = OpenILS::Event->new('USER_NOT_FOUND');
336                         return (undef, $evt);
337                 }
338                 $evt = $self->check_perms( $staffobj->id, $user->home_ou, @perms );
339
340         } else {
341                 $user = $staffobj;
342         }
343
344         return ($user, $evt);
345 }
346
347 sub checkses_requestor {
348         my( $self, $authtoken, $targetid, @perms ) = @_;
349         my( $requestor, $target, $evt );
350
351         ($requestor, $evt) = $self->checkses($authtoken);
352         return (undef, undef, $evt) if $evt;
353
354         ($target, $evt) = $self->checkrequestor( $requestor, $targetid, @perms );
355         return( $requestor, $target, $evt);
356 }
357
358
359
360
361
362 1;