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