more session management; transient sessions
authorBill Erickson <berickxx@gmail.com>
Mon, 12 Oct 2020 20:13:14 +0000 (16:13 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 28 Oct 2020 18:57:39 +0000 (14:57 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/examples/fm_IDL.xml
Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Common.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Patron.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Session.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/SIP2Mediator.pm
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.sip-config.sql

index 7236968..75d637f 100644 (file)
@@ -13491,7 +13491,7 @@ SELECT  usr,
                        <field name="sip_username" reporter:datatype="text" reporter:label="SIP Username" oils_obj:required="true"/>
                        <field name="usr" reporter:datatype="link" reporter:label="ILS User" oils_obj:required="true"/>
                        <field name="workstation" reporter:datatype="link" reporter:label="Workstation"/>
-                       <field name="ephemeral" reporter:datatype="bool" reporter:label="Ephemeral"/>
+                       <field name="transient" reporter:datatype="bool" reporter:label="Transient"/>
                        <field name="activity_who" reporter:datatype="text" reporter:label="Activity Who"/>
                </fields>
                <links>
index f7138dd..860f906 100644 (file)
@@ -1,7 +1,6 @@
 package OpenILS::Application::SIP2;
 use strict; use warnings;
 use base 'OpenILS::Application';
-use OpenSRF::Utils::Cache;
 use OpenILS::Application;
 use OpenILS::Event;
 use OpenILS::Utils::Fieldmapper;
@@ -62,10 +61,10 @@ sub dispatch_sip2_request {
     }
 
     my $MESSAGE_MAP = {
-        'XS' => \&handle_end_session,
         '17' => \&handle_item_info,
         '23' => \&handle_patron_status,
-        '63' => \&handle_patron_info
+        '63' => \&handle_patron_info,
+        'XS' => \&handle_end_session
     };
 
     return OpenILS::Event->new('SIP2_NOT_IMPLEMENTED', {payload => $message})
@@ -77,15 +76,23 @@ sub dispatch_sip2_request {
 sub handle_end_session {
     my ($session, $message) = @_;
     my $e = $session->editor;
+    my $seskey = $session->seskey;
 
-    my $ses = $e->retrieve_sip_session($session->seskey) || return;
-
-    $e->xact_begin;
-    $e->delete_sip_session($ses);
-    $e->commit;
+    $SC->cache->delete_cache("sip2_$seskey");
 
     $U->simplereq('open-ils.auth', 
-        'open-ils.auth.session.delete', $ses->ils_token);
+        'open-ils.auth.session.delete', $e->authtoken);
+
+    return undef if $U->is_true($session->sip_account->transient);
+
+    $e->xact_begin;
+    my $ses = $e->retrieve_sip_session($seskey);
+    if ($ses) {
+        $e->delete_sip_session($ses);
+        $e->commit;
+    } else {
+        $e->rollback;
+    }
 
     return undef;
 }
index 8433775..e515bf2 100644 (file)
@@ -1,9 +1,16 @@
 package OpenILS::Application::SIP2::Common;
 use strict; use warnings;
 use OpenILS::Utils::DateTime qw/:datetime/;
+use OpenSRF::Utils::Cache;
 
 use constant SIP_DATE_FORMAT => "%Y%m%d    %H%M%S";
 
+my $_cache;
+sub cache {
+    $_cache = OpenSRF::Utils::Cache->new unless $_cache;
+    return $_cache;
+}
+
 sub sipdate {
     my ($class, $date) = @_;
     $date ||= DateTime->now;
index 0bc404d..40d118a 100644 (file)
@@ -163,6 +163,8 @@ sub set_patron_summary_list_items {
 
     my $list_items = $params{summary_list_items};
 
+    return unless $list_items;
+
     # Start and end are 1-based.  Translate to zero-based for internal use.
     my $offset = $params{summary_start_item} ? $params{summary_start_item} - 1 : 0;
     my $end = $params{summary_end_item} ? $params{summary_end_item} - 1 : 10;
index 4067a60..3639eaa 100644 (file)
@@ -5,8 +5,10 @@ use OpenSRF::Utils::Logger q/$logger/;
 use OpenILS::Application::AppUtils;
 use OpenILS::Utils::CStoreEditor q/:funcs/;
 use OpenILS::Utils::Fieldmapper;
-my $U = 'OpenILS::Application::AppUtils';
+use OpenILS::Application::SIP2::Common;
 my $json = JSON::XS->new;
+my $U = 'OpenILS::Application::AppUtils';
+my $SC = 'OpenILS::Application::SIP2::Common';
 $json->ascii(1);
 $json->allow_nonref(1);
 
@@ -67,23 +69,27 @@ sub find {
     my $session = $class->new(seskey => $seskey);
     my $e = $session->editor;
 
+    my $cache_ses = $SC->cache->get_cache("sip2_$seskey");
+
+    if ($cache_ses) {
+        $session->{sip_account} = $cache_ses->{sip_account};
+        $e->authtoken($cache_ses->{ils_token});
+        return $session if $session->set_ils_account;
+    }
+
+    # Nothing in the cache, check the DB.
+
     my $ses = $e->retrieve_sip_session([
         $seskey, {flesh => 1, flesh_fields => {sipses => ['account']}}]);
 
     if ($ses) {
         $session->{sip_account} = $ses->account;
-
         $e->authtoken($ses->ils_token);
-
-        return $session if $session->set_ils_account;
-
-        return undef;
-
-    } else {
-
-        $logger->warn("SIP2: No session found for key $seskey");
-        return undef;
+        return $session if $session->set_ils_account($ses);
     }
+
+    $logger->warn("SIP2: No session found for key $seskey");
+    return undef;
 }
 
 # The editor contains the authtoken and ILS user account (requestor).
@@ -109,13 +115,11 @@ sub sip_account {
 # Returns true on success, false on failure to authenticate.
 sub set_ils_account {
     my $self = shift;
+    my $ses = shift;
     my $e = $self->editor;
 
-    # Verify previously applied authtoken is still valid.
     return 1 if $e->authtoken && $e->checkauth;
 
-    my $seskey = $self->seskey;
-
     my $auth = $U->simplereq(
         'open-ils.auth_internal',
         'open-ils.auth_internal.session.create', {
@@ -131,18 +135,44 @@ sub set_ils_account {
         return 0;
     }
 
-    # Ephemeral account sessions are not tracked in the database
-    return 1 if $U->is_true($self->sip_account->ephemeral);
+    my $seskey = $self->seskey;
+    my $ils_token = $auth->{payload}->{authtoken};
+    $e->authtoken($ils_token);
+
+    my $cache_ses = {
+        sip_account => $self->sip_account,
+        ils_token => $ils_token
+    };
+
+    $SC->cache->put_cache("sip2_$seskey", $cache_ses);
 
-    my $ses = Fieldmapper::sip::session->new;
-    $ses->key($seskey);
-    $ses->ils_token($auth->{payload}->{authtoken});
-    $ses->account($self->sip_account->id);
+    # transient account sessions are not tracked in the database
+    return 1 if $U->is_true($self->sip_account->transient);
 
     $e->xact_begin;
-    unless ($e->create_sip_session($ses)) {
-        $e->rollback;
-        return 0;
+
+    if ($ses) {
+        # ILS token expired on an existing SIP session.
+        # Update the session to use the new token.
+
+        $ses->ils_token($ils_token);
+        unless ($e->udpate_sip_session($ses)) {
+            $e->rollback;
+            return 0;
+        }
+            
+    } else {
+        # New session
+
+        my $ses = Fieldmapper::sip::session->new;
+        $ses->key($seskey);
+        $ses->ils_token($ils_token);
+        $ses->account($self->sip_account->id);
+
+        unless ($e->create_sip_session($ses)) {
+            $e->rollback;
+            return 0;
+        }
     }
 
     $e->xact_commit;
index b703053..90eae94 100644 (file)
@@ -74,6 +74,10 @@ sub handler {
         'open-ils.sip2.request', $seskey, $message);
 
     if (!$response) {
+
+        # It's OK not receive a response after an End Session message
+        return Apache2::Const::OK if $msg_code eq 'XS';
+
         $logger->error("SIP2: API Request returned no value for: $msg_json");
         return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
 
index 7d22e45..2b164eb 100644 (file)
@@ -36,8 +36,8 @@ CREATE TABLE sip.account (
     usr             BIGINT NOT NULL REFERENCES actor.usr(id)
                     DEFERRABLE INITIALLY DEFERRED,
     workstation     INTEGER REFERENCES actor.workstation(id),
-    -- sessions for ephemeral accounts are not tracked in sip.session
-    ephemeral       BOOLEAN NOT NULL DEFAULT FALSE,
+    -- sessions for transient accounts are not tracked in sip.session
+    transient       BOOLEAN NOT NULL DEFAULT FALSE,
     activity_who    TEXT -- config.usr_activity_type.ewho
 );