OverDrive API Integration Does Not Work When Password Required

Bug #1861013 reported by Jason Stephenson on 2020-01-27
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Evergreen
Medium
Unassigned
3.3
Undecided
Unassigned
3.4
Undecided
Unassigned

Bug Description

The ebook_api.overdrive.password_required org. unit setting does not work. It causes code with an onClick handler to be added to the OPAC login form. This code triggers as soon as any widget in the form is clicked. The code attempts to cache the user's password in the Evergreen session cache for the user. However, the user is not logged in at the time this code runs, so no such session or session cache exist, yet. Thus, the user's password is never cached. Below is the console log showing the failure of the oncomplete handler from the attempt to cache the password:

JavaScript Console Log:
starting ebook API session for overdrive
login?redirect_to=%2Feg%2Fopac%2Fmyopac%2Fmain:2291 Uncaught TypeError: Cannot read property 'value' of null
    at login?redirect_to=%2Feg%2Fopac%2Fmyopac%2Fmain:2291
    at OpenSRF.Request.oncomplete (session.js?f456c8:14)
    at Function.OpenSRF.Stack.handle_message (opensrf.js?f456c8:713)
    at Function.OpenSRF.Stack.push (opensrf.js?f456c8:693)
    at OpenSRF.XHRequest.core_handler (opensrf_xhr.js?f456c8:106)
    at XMLHttpRequest.xreq.onreadystatechange (opensrf_xhr.js?f456c8:59)
(anonymous) @ login?redirect_to=%2Feg%2Fopac%2Fmyopac%2Fmain:2291
oncomplete @ session.js?f456c8:14
OpenSRF.Stack.handle_message @ opensrf.js?f456c8:713
OpenSRF.Stack.push @ opensrf.js?f456c8:693
OpenSRF.XHRequest.core_handler @ opensrf_xhr.js?f456c8:106
xreq.onreadystatechange @ opensrf_xhr.js?f456c8:59
XMLHttpRequest.send (async)
OpenSRF.XHRequest.send @ opensrf_xhr.js?f456c8:89
OpenSRF.Session.send_xhr @ opensrf.js?f456c8:309
OpenSRF.Session.send @ opensrf.js?f456c8:299
OpenSRF.Request.send @ opensrf.js?f456c8:612
startSession @ session.js?f456c8:17
checkSession @ session.js?f456c8:25
(anonymous) @ login?redirect_to=%2Feg%2Fopac%2Fmyopac%2Fmain:2290
(anonymous) @ login?redirect_to=%2Feg%2Fopac%2Fmyopac%2Fmain:2288
(anonymous) @ dojo.js?f456c8:16

The user's password will need to be cached after the login is successful, and the OILS AUTH session is available.

Additionally, the current code uses Dojo to install an onload function to set up the onclick. This is another place that will need to be touched when we do finally remove Dojo from Evergreen.

Jeff Davis (jdavis-sitka) wrote :

The password is stored in the ebook_api session cache, which is separate from the main Evergreen session cache. The user does not need to be logged in to Evergreen for an ebook_api session to exist. EG should be verifying the existence of an ebook_api session (or initiating one) first, then caching the password via a callback function. Or at least that's the intended behavior -- there is clearly a bug here.

tags: added: overdrive
Jason Stephenson (jstephenson) wrote :

Jeff, what do you think about moving the creation of the EbookAPI session and the cache of the user's password to the OPAC login code that runs on the server? The login routine on the server has access to the patron's plaintext password and can do all of the other required steps. This should also reduce the number of HTTP callbacks to the server, thus making things work a bit more smoothly. This change means changing code in EGCatLoader.pm (Perl) and removing a template and removing some template code to load said template. There may be additional changes required beyond this.

Changed in evergreen:
status: New → Confirmed
importance: Undecided → Medium
Jeff Davis (jdavis-sitka) wrote :

EbookAPI was implemented in JS so that the rest of the OPAC would work fine even if there are problems with the external API -- we don't want to wait for a response from Overdrive's API before logging the user in or rendering an OPAC page. We'd also have to deal with the fact that the user is likely to have an active EbookAPI session already before they login (a common flow: search the catalogue, find an Overdrive title, click on "Check out E-book", get bounced to the login page).

But if we can get past those hurdles, moving EbookAPI auth stuff to the server would be fine by me. Fewer server calls and no client-side password handling would be great.

Jason Stephenson (jstephenson) wrote :

Jeff, given your response in comment #3, it makes sense to me that this is done in JavaScript.

I think there needs to be a major change to how this works: The patron's password should not be cached until after their OPAC login is successful. This way, we avoid caching a typo. Doing this in JavaScript in the browser is a great deal more complicated than doing it in the back end code. The browser would need to store the plaintext password somewhere (a cookie?) while the back end does it's thing, and then cache it when the login is successful. I suppose it could cache the password when the login form is submitted, and then remove it from the cache if the login fails.

Then, there is the issue of the cache call failing.

There's also the question of having a separate Ebook API session. Is this of any use if the patron is not logged into the OPAC, yet? If no, then why have it all? The relevant data could be added as keys on the patron's OPAC session. If yes, then OK, perhaps we need better code to retrieve one that already exists when a patron logs into the OPAC. (Your comment makes it sound like that isn't possible from the back end at least.) Maybe a cookie will work here?

Jeff Davis (jdavis-sitka) wrote :

I'm not sure what problem we solve by waiting for successful OPAC login before caching the password. The open-ils.ebook_api.patron.cache_password call will overwrite any existing cached password for the current EbookAPI session, so if there's a typo, the cache should be updated with the correct value when the user re-enters their password correctly. Currently, if the patron enters a bad password, at worst we send off a bad auth request to Overdrive, which fails; if they subsequently enter the correct password, there is a subsequent Overdrive auth request, which succeeds -- or at least it would succeed if password caching was working.

We need an EbookAPI session prior to OPAC login because you can't look up title and availability info without obtaining a client access token from the API, and the EbookAPI session is where that token is stored by Evergreen. The session is created and managed by the server, not the browser, in order to avoid exposing the library's client key, secret, etc. to the end user during the client access request. We use that same EbookAPI session for password caching and patron auth related stuff (checkouts, holds, etc.) because it keeps things simple, and because other APIs might not be as good as Overdrive at making a clean distinction between "client" and "patron" authorization.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers