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);
7 use OpenSRF::Utils::Logger;
8 my $logger = "OpenSRF::Utils::Logger";
11 my $cache_client = "OpenSRF::Utils::Cache";
13 # ---------------------------------------------------------------------------
14 # Pile of utilty methods used accross applications.
15 # ---------------------------------------------------------------------------
18 # ---------------------------------------------------------------------------
19 # on sucess, returns the created session, on failure throws ERROR exception
20 # ---------------------------------------------------------------------------
21 sub start_db_session {
24 my $session = OpenSRF::AppSession->connect( "open-ils.storage" );
25 my $trans_req = $session->request( "open-ils.storage.transaction.begin" );
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() ) {
31 ("Unable to Begin Transaction with database" );
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 ) = @_;
43 $logger->debug("Checking perms with user : $user_id , org: $org_id, @perm_types");
45 throw OpenSRF::EX::ERROR ("Invalid call to check_user_perms()")
46 unless( defined($user_id) and defined($org_id) and @perm_types);
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);
55 $session->disconnect();
60 $session->disconnect();
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
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;
75 # ---------------------------------------------------------------------------
76 # commits and destroys the session
77 # ---------------------------------------------------------------------------
78 sub commit_db_session {
79 my( $self, $session ) = @_;
81 my $req = $session->request( "open-ils.storage.transaction.commit" );
82 my $resp = $req->recv();
85 throw OpenSRF::EX::ERROR ("Unable to commit db session");
88 if(UNIVERSAL::isa($resp,"Error")) {
89 throw $resp ($resp->stringify);
93 throw OpenSRF::EX::ERROR ("Unable to commit db session");
97 $session->disconnect();
101 sub rollback_db_session {
102 my( $self, $session ) = @_;
104 my $req = $session->request("open-ils.storage.transaction.rollback");
105 my $resp = $req->recv();
106 if(UNIVERSAL::isa($resp,"Error")) { throw $resp; }
109 $session->disconnect();
113 # ---------------------------------------------------------------------------
114 # Checks to see if a user is logged in. Returns the user record on success,
115 # throws an exception on error.
116 # ---------------------------------------------------------------------------
118 my( $self, $session ) = @_;
122 $user = $self->check_user_session($session);
124 $evt = OpenILS::Event->new('NO_SESSION');
127 return ( $user, $evt );
130 sub check_user_session {
132 my( $self, $user_session ) = @_;
134 my $session = OpenSRF::AppSession->create( "open-ils.auth" );
135 my $request = $session->request("open-ils.auth.session.retrieve", $user_session );
136 my $response = $request->recv();
139 throw OpenSRF::EX::User
140 ("Error communication with storage server");
143 if( ref($response) eq 'HASH' ) {
144 if(defined($response->{ilsevent}) and $response->{ilsevent} ne '0' ) {
145 throw OpenSRF::EX::ERROR
146 ("Session [$user_session] cannot be authenticated" );
151 if(ref($response) and $response->isa("OpenSRF::EX")) {
152 throw $response ($response->stringify);
155 my $user = $response->content;
157 throw OpenSRF::EX::ERROR ("Session [$user_session] cannot be authenticated" );
160 $session->disconnect();
166 # generic simple request returning a scalar value
168 my($self, $service, $method, @params) = @_;
169 return $self->simple_scalar_request($service, $method, @params);
173 sub simple_scalar_request {
174 my($self, $service, $method, @params) = @_;
176 my $session = OpenSRF::AppSession->create( $service );
177 my $request = $session->request( $method, @params );
178 my $response = $request->recv(30);
180 $request->wait_complete;
182 if(!$request->complete) {
183 throw OpenSRF::EX::ERROR ("Call to $service for method $method with params @params" .
184 "\n did not complete successfully");
188 warn "No response from $service for method $method with params @params";
191 if(UNIVERSAL::isa($response,"Error")) {
192 throw $response ("Call to $service for method $method with params @params" .
193 "\n failed with exception: " . $response->stringify );
199 $session->disconnect();
203 if($response) { $value = $response->content; }
204 else { $value = undef; }
215 my $org_typelist = undef;
216 my $org_typelist_hash = {};
221 if($tree) { return $tree; }
223 # see if it's in the cache
224 $tree = $cache_client->new()->get_cache('_orgtree');
225 if($tree) { return $tree; }
228 warn "Retrieving Org Tree\n";
229 $orglist = $self->simple_scalar_request(
231 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
234 if( ! $org_typelist ) {
235 warn "Retrieving org types\n";
236 $org_typelist = $self->simple_scalar_request(
238 "open-ils.storage.direct.actor.org_unit_type.retrieve.all.atomic" );
239 $self->build_org_type($org_typelist);
242 $tree = $self->build_org_tree($orglist,1);
243 $cache_client->new()->put_cache('_orgtree', $tree);
248 my $slimtree = undef;
249 sub get_slim_org_tree {
252 if($slimtree) { return $slimtree; }
254 # see if it's in the cache
255 $slimtree = $cache_client->new()->get_cache('slimorgtree');
256 if($slimtree) { return $slimtree; }
259 warn "Retrieving Org Tree\n";
260 $orglist = $self->simple_scalar_request(
262 "open-ils.storage.direct.actor.org_unit.retrieve.all.atomic" );
265 $slimtree = $self->build_org_tree($orglist);
266 $cache_client->new->put_cache('slimorgtree', $slimtree);
273 my($self, $org_typelist) = @_;
274 for my $type (@$org_typelist) {
275 $org_typelist_hash->{$type->id()} = $type;
283 my( $self, $orglist, $add_types ) = @_;
285 return $orglist unless (
286 ref($orglist) and @$orglist > 1 );
289 $a->ou_type <=> $b->ou_type ||
290 $a->name cmp $b->name } @$orglist;
292 for my $org (@list) {
296 if(!ref($org->ou_type()) and $add_types) {
297 $org->ou_type( $org_typelist_hash->{$org->ou_type()});
300 next unless (defined($org->parent_ou));
302 my ($parent) = grep { $_->id == $org->parent_ou } @list;
304 $parent->children([]) unless defined($parent->children);
305 push( @{$parent->children}, $org );
315 return $self->simple_scalar_request(
317 'open-ils.storage.direct.actor.user.retrieve', $id );
322 # handy tool to handle the ever-recurring situation of someone requesting
323 # something on someone else's behalf (think staff member creating something for a user)
324 # returns ($requestor, $targetuser_id, $event );
325 # $event may be a PERM_FAILURE event or a NO_SESSION event
326 # $targetuser == $staffuser->id when $targetuser is undefined.
327 sub handle_requestor {
328 my( $self, $authtoken, $targetuser, @permissions ) = @_;
330 my( $requestor, $evt ) = $self->check_ses($authtoken);
331 return (undef, undef, $evt) if $evt;
333 $targetuser = $requestor->id unless defined $targetuser;
334 my $userobj = $requestor;
335 $userobj = $self->fetch_user($targetuser)
336 unless $targetuser eq $requestor->id;
338 if(!$userobj) {} # XXX Friendly exception
342 #everyone is allowed to view their own data
343 if( $targetuser ne $requestor->id ) {
344 $perm = $self->check_perms(
345 $requestor->id, $userobj->home_ou, @permissions );
348 return ($requestor, $targetuser, $perm);