LP#1282783 - Improve the processing in the KPAC to pass along notification user/dpearl/kpac
authorDan Pearl <dpearl@cwmars.org>
Wed, 23 Jul 2014 18:18:32 +0000 (14:18 -0400)
committerDan Pearl <dpearl@cwmars.org>
Wed, 23 Jul 2014 18:32:32 +0000 (14:32 -0400)
information in holds, as well as pre-initialize the pickup location correctly.
A new login screen has been created.

Signed-off-by: Dan Pearl <dpearl@cwmars.org>
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGKPacLoader.pm
Open-ILS/src/templates/kpac/getit.tt2
Open-ILS/src/templates/kpac/login.tt2 [new file with mode: 0644]
Open-ILS/src/templates/kpac/parts/header.tt2
Open-ILS/src/templates/kpac/parts/login_form.tt2 [new file with mode: 0644]
docs/RELEASE_NOTES_NEXT/OPAC/KPAC_improvements.txt [new file with mode: 0644]

index 30fbca2..0f62033 100644 (file)
@@ -9,6 +9,9 @@ use OpenILS::Utils::CStoreEditor qw/:funcs/;
 my $U = 'OpenILS::Application::AppUtils';
 my $kpac_config;
 
+use constant COOKIE_SES => 'ses';
+use constant COOKIE_LOGGEDIN => 'eg_loggedin';
+
 # -----------------------------------------------------------------------------
 # Override our parent's load() sub so we can do kpac-specific path routing.
 # -----------------------------------------------------------------------------
@@ -36,13 +39,30 @@ sub load {
     # ----------------------------------------------------------------
     return $self->redirect_ssl unless $self->cgi->https;
 
-    return $self->load_getit_results if $path =~ m|kpac/getit_results|;
-    return $self->load_getit if $path =~ m|kpac/getit|;
+    if ($path =~ m|kpac/login|) {
+       return $self->load_login unless $self->editor->requestor; # already logged in?
+
+       # This will be less confusing to users than to be shown a login form
+       # when they're already logged in.
+
+       return $self->generic_redirect($self->ctx->{home_page});
+    }
 
     # ----------------------------------------------------------------
     #  Everything below here requires authentication
     # ----------------------------------------------------------------
-    return $self->redirect_auth unless $self->editor->requestor;
+    if (!$self->editor->requestor) {
+         my $tpac_root = $self->ctx->{opac_root};
+         $self->ctx->{opac_root} = $self->ctx->{kpac_root};
+
+         my $login = $self->redirect_auth;
+         $self->ctx->{opac_root} = $tpac_root;
+
+         return $login;
+    }
+
+    return $self->load_getit_results if $path =~ m|kpac/getit_results|;
+    return $self->load_getit if $path =~ m|kpac/getit|;
 
     # AUTH pages
 
@@ -77,6 +97,12 @@ sub load_getit {
 
     $self->ctx->{page} = 'getit'; # repair the page
 
+    # If we have a default pickup location, grab it
+    my $user_setting_map = $ctx->{user_setting_map};
+    if ($$user_setting_map{'opac.default_pickup_location'}) {
+        $ctx->{default_pickup_lib} = $$user_setting_map{'opac.default_pickup_location'};
+    }
+
     return $self->save_item_to_bookbag($rec_id, $bbag_id) if $action eq 'save';
     return $self->login_and_place_hold($rec_id) if $action eq 'hold';
 
@@ -209,6 +235,7 @@ sub load_getit_results {
     return Apache2::Const::OK;
 }
 
+
 sub load_kpac_config {
     my $self = shift;
     my $ctx = $self->ctx;
@@ -247,4 +274,136 @@ sub load_kpac_config {
 }
 
 
+# -----------------------------------------------------------------------------
+# Log in and redirect to the redirect_to URL (or home)
+# -----------------------------------------------------------------------------
+sub load_kpac_login {
+    my $self = shift;
+    my $cgi = $self->cgi;
+    my $ctx = $self->ctx;
+
+    $self->timelog("Load login begins");
+
+    $ctx->{page} = 'login';
+
+    my $username = $cgi->param('username');
+    $username =~ s/\s//g;  # Remove blanks
+    my $password = $cgi->param('password');
+    my $org_unit = $ctx->{physical_loc} || $ctx->{aou_tree}->()->id;
+    my $persist = $cgi->param('persist');
+
+    # initial log form only
+    return Apache2::Const::OK unless $username and $password;
+
+    my $auth_proxy_enabled = 0; # default false
+    try { # if the service is not running, just let this fail silently
+        $auth_proxy_enabled = $U->simplereq(
+            'open-ils.auth_proxy',
+            'open-ils.auth_proxy.enabled');
+    } catch Error with {};
+
+    $self->timelog("Checked for auth proxy: $auth_proxy_enabled; org = $org_unit; username = $username");
+
+    my $args = {
+        type => ($persist) ? 'persist' : 'opac',
+        org => $org_unit,
+        agent => 'opac'
+    };
+
+    my $bc_regex = $ctx->{get_org_setting}->($org_unit, 'opac.barcode_regex');
+
+    # To avoid surprises, default to "Barcodes start with digits"
+    $bc_regex = '^\d' unless $bc_regex;
+
+    if ($bc_regex and ($username =~ /$bc_regex/)) {
+        $args->{barcode} = $username;
+    } else {
+        $args->{username} = $username;
+    }
+
+    my $response;
+    if (!$auth_proxy_enabled) {
+        my $seed = $U->simplereq(
+            'open-ils.auth',
+            'open-ils.auth.authenticate.init', $username);
+        $args->{password} = md5_hex($seed . md5_hex($password));
+        $response = $U->simplereq(
+            'open-ils.auth', 'open-ils.auth.authenticate.complete', $args);
+    } else {
+        $args->{password} = $password;
+        $response = $U->simplereq(
+            'open-ils.auth_proxy',
+            'open-ils.auth_proxy.login', $args);
+    }
+    $self->timelog("Checked password");
+
+    if($U->event_code($response)) { 
+        # login failed, report the reason to the template
+        $ctx->{login_failed_event} = $response;
+        return Apache2::Const::OK;
+    }
+
+    # login succeeded, redirect as necessary
+
+    my $acct = $self->apache->unparsed_uri;
+    $acct =~ s|/login|/home|; ### /myopac/main
+
+    # both login-related cookies should expire at the same time
+    my $login_cookie_expires = ($persist) ? CORE::time + $response->{payload}->{authtime} : undef;
+
+    return $self->generic_redirect(
+        $cgi->param('redirect_to') || $acct,
+        [
+            # contains the actual auth token and should be sent only over https
+            $cgi->cookie(
+                -name => COOKIE_SES,
+                -path => '/',
+                -secure => 1,
+                -value => $response->{payload}->{authtoken},
+                -expires => $login_cookie_expires
+            ),
+            # contains only a hint that we are logged in, and is used to
+            # trigger a redirect to https
+            $cgi->cookie(
+                -name => COOKIE_LOGGEDIN,
+                -path => '/',
+                -secure => 0,
+                -value => '1',
+                -expires => $login_cookie_expires
+            )
+        ]
+    );
+}
+# -----------------------------------------------------------------------------
+# Log out and redirect to the home page
+# -----------------------------------------------------------------------------
+sub load_logout {
+    my $self = shift;
+    my $redirect_to = shift || $self->cgi->param('redirect_to');
+
+    # If the user was adding anyting to an anonymous cache 
+    # while logged in, go ahead and clear it out.
+    $self->clear_anon_cache;
+
+    return $self->generic_redirect(
+        $redirect_to || $self->ctx->{home_page},
+        [
+            # clear value of and expire both of these login-related cookies
+            $self->cgi->cookie(
+                -name => COOKIE_SES,
+                -path => '/',
+                -value => '',
+                -expires => '-1h'
+            ),
+            $self->cgi->cookie(
+                -name => COOKIE_LOGGEDIN,
+                -path => '/',
+                -value => '',
+                -expires => '-1h'
+            )
+        ]
+    );
+}
+
+
 1;
index a807b0d..79aff7c 100644 (file)
                                 </div>
                             </div>
                         </div>
+
+                       [%- IF ctx.user.email -%]
+                           <input type="hidden" id="email_notify" name="email_notify" value="t"/>
+                       [%- END -%]
+
+                       [%- IF allow_phone_notifications == 'true' -%]
+                           <input type="hidden" id="phone_notify_checkbox" name="phone_notify_checkbox" value="t"/>
+                           <input type="hidden" name="phone_notify" [% setting = 'opac.default_phone';
+                           IF ctx.user_setting_map.$setting; %] value='[% ctx.user_setting_map.$setting | html %]'
+                           [%- ELSIF ctx.user.day_phone; %] value='[% ctx.user.day_phone | html %]' [%- END -%]/>
+                       [%- END;
+
+                        setting = 'opac.default_sms_carrier';
+                        IF ctx.user_setting_map.$setting AND ctx.get_org_setting(ctx.search_ou, 'sms.enable') == 1 AND ctx.default_sms_notify; 
+                            default_carrier = ctx.user_setting_map.$setting -%]
+                           <input type="hidden" id="sms_notify_checkbox" name="sms_notify_checkbox" value="T"/>
+                            <input type="hidden" name="sms_carrier" value='[% default_carrier %]'/>
+                            <input type="hidden" name="sms_notify" [% setting = 'opac.default_sms_notify';
+                            IF ctx.user_setting_map.$setting; %] value='[% ctx.user_setting_map.$setting | html %]' [% END %]/>
+                       [%- END -%]
+
                         <div class="submit_btn">
                             <input type='hidden' name='action' value='hold'/>
                             <input type='image' src="[% ctx.media_prefix %]/images/kpac/review_submit_btn.png" alt="[% l('Submit') %]"/>
diff --git a/Open-ILS/src/templates/kpac/login.tt2 b/Open-ILS/src/templates/kpac/login.tt2
new file mode 100644 (file)
index 0000000..c72631c
--- /dev/null
@@ -0,0 +1,11 @@
+[%- PROCESS "opac/parts/header.tt2";
+    WRAPPER "kpac/parts/base.tt2";
+    basic_search = "f";
+    ctx.page_title = l("Login") %]
+    <div id="content-wrapper">
+        <div id="main-content">
+            [% INCLUDE "kpac/parts/login_form.tt2" %]
+            <div class="clear-both very-big-height"></div>     
+        </div>
+    </div>
+[%- END %]
index 588b910..180565c 100644 (file)
                 {redirect_to => redir.replace('^https:', 'http:')}, 1) %]">[% 
                     l('Logout ([_1] [_2])', ctx.user.first_given_name, ctx.user.family_name) %]</a>
         [% ELSE %]
-            <a href="[% mkurl(ctx.opac_root _ '/login').replace('^http:', 'https:') %]">[% l('Login') %]</a>
+            [% IF ctx.page_title != 'Login' %]
+               [% redir = CGI.url('-base' => 1) _ ctx.kpac_root _ '/home' %]
+               <a href="[% mkurl(ctx.kpac_root _ '/login',
+                {redirect_to => redir.replace('^http:', 'https:')}, 1) %]">[% 
+                    l('Login') %]</a>
+            [% END %]
         [% END %]
         <a href="javascript:;">[% l('Get a Library Card') %]</a>
         <a href="javascript:;">[% l('Help') %]</a>
diff --git a/Open-ILS/src/templates/kpac/parts/login_form.tt2 b/Open-ILS/src/templates/kpac/parts/login_form.tt2
new file mode 100644 (file)
index 0000000..bb22fb7
--- /dev/null
@@ -0,0 +1,94 @@
+[% IF ctx.login_failed_event %]
+<div id='login-failed-message' style="color:#F00;font-size:20px;">
+[%
+    IF ctx.login_failed_event.textcode == 'PATRON_CARD_INACTIVE';
+        l("The barcode used to login is marked as inactive.  Please contact your local library.");
+    ELSIF ctx.login_failed_event.textcode == 'PATRON_INACTIVE';
+        l("This account has been deactivated.  Please contact your local library.");
+    ELSE;
+        l("Login failed. The username or password provided was not valid. " _
+           "Passwords are case-sensitive.  Check your Caps-Lock key and try again or contact your local library.");
+    END;
+%]
+</div>
+[% END %]
+<div class="checkout_options">
+    <table cellpadding="0" cellspacing="0" border="0">
+        <tr>
+            <td valign="top" class="left_brain_cell">
+                <div class="left_brain">
+
+                    [% WRAPPER 'kpac/parts/help_popups.tt2' popup_id='card_help' %]
+                        <img src="[% ctx.media_prefix %]/images/kpac/library_card.png" alt="[% l('library card') %]" /></div></td>
+                    [% END %]
+                    [% WRAPPER 'kpac/parts/help_popups.tt2' popup_id='password_help' %]
+                        <p>[% l('Enter your password') %]</p>
+                    [% END %]
+
+                    <div class="top_side">
+                        <h2>[% l('login') %]</h2>
+                    </div>
+
+                    <form method='POST'><!-- login -->
+
+                        <div class="checkout_box">
+                            <div class="box1_top">&nbsp;</div>
+                            <div class="box_inside">
+
+                                [% IF !ctx.user %]
+                                    [% seed = l(' Enter Numbers... ') %]
+                                    <p>[% l('Library Card Number:') %]</p>
+                                    <div class="input_box">
+                                        <input name="username" tabindex="1" type="text" class="text_box" style="color:#aaa;" value="[% seed %]" 
+                                            onfocus="if(this.value=='[% seed %]'){this.value='';this.style.color='#424242';}" 
+                                            onblur="if(this.value==''){this.value='[% seed %]'; this.style.color='#aaa';}" />
+                                    </div>
+                                    <a class="help_btn" href="javascript:;" 
+                                        onclick="helpPopup('card_help', this, event);"><img 
+                                        src="[% ctx.media_prefix %]/images/kpac/question_mark.png" alt="[% l('pin number help') %]" /></a>
+
+                                    <div class="clear">&nbsp;</div>
+                                    <div class="hr">&nbsp;</div>
+
+                                    <p>[% l('Password') %]</p>
+                                    <div class="input_box">
+                                        <input name="password" tabindex="2" type="password" class="text_box" style="color:#aaa;" value="[% seed %]" 
+                                            onfocus="if(this.value=='[% seed %]'){this.value='';this.style.color='#424242';}" 
+                                            onblur="if(this.value==''){this.value='[% seed %]'; this.style.color='#aaa';}" />
+                                    </div>
+
+                                    <a class="help_btn" href="javascript:;" 
+                                        onclick="helpPopup('password_help', this, event);"><img 
+                                        src="[% ctx.media_prefix %]/images/kpac/question_mark.png" alt="[% l('password help') %]" /></a>
+
+                                    <div class="clear">&nbsp;</div>
+                                    <div class="hr">&nbsp;</div>
+                                [% END %]
+
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="submit_btn">
+                            <input type='hidden' name='action' value='hold'/>
+                            <input type='image' src="[% ctx.media_prefix %]/images/kpac/review_submit_btn.png" alt="[% l('Submit') %]"/>
+                        </div>
+
+                       <div id='login-form-box' class='login_boxes left_brain' style='float:left'>
+                         [%
+                           # If no redirect is offered or it's leading us back to the
+                           # login form, redirect the user to My Account
+                           redirect = CGI.param('redirect_to') || ctx.referer;
+                           IF !redirect OR redirect.match(ctx.path_info _ '$');
+                               redirect = CGI.url('-full' => 1) _ '/kpac/home';
+                           END;
+                               redirect = redirect  | replace('^http:', 'https:');
+                           %]
+                           <input type='hidden' name='redirect_to' value='[% redirect %]'/>
+                       </div><!-- checkout box -->
+                   </form><!-- login -->
+                </div><!-- left brain -->
+            </td><!-- left brain cell -->
+        </tr>
+    </table>
+</div>
diff --git a/docs/RELEASE_NOTES_NEXT/OPAC/KPAC_improvements.txt b/docs/RELEASE_NOTES_NEXT/OPAC/KPAC_improvements.txt
new file mode 100644 (file)
index 0000000..aaf4bd2
--- /dev/null
@@ -0,0 +1,11 @@
+Improvement to KPAC Hold Processing
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The pickup location in the GetIt screen is now initialized with the choice in the patron's record.
+The patron's email address, SMS and phone information is now stored in the hold request.
+This is accomplished by ensuring that the patron is logged in before the GetIt screen is displayed.
+
+To accomplish this, the KPAC now divert to a new Login screen before the GetIt screen is shown if 
+the patron is not yet logged in.
+This mirrors the paradigm of the OPAC.
+
+The Login screen can be explicitly invoked with the "Login" control, and is rendered with KPAC styling.